Question

I have created a factory class called AlarmFactory as such...

1    class AlarmFactory
2    {
3        public static Alarm GetAlarm(AlarmTypes alarmType)  //factory ensures that correct alarm is returned and right func pointer for trigger creator.
4        {
5            switch (alarmType)
6            {
7                case AlarmTypes.Heartbeat:
8                    HeartbeatAlarm alarm = HeartbeatAlarm.GetAlarm();
9                    alarm.CreateTriggerFunction = QuartzAlarmScheduler.CreateMinutelyTrigger;
10                    return alarm;
11
12                   break;
13                default:
14                
15                    break;
16            }
17        }
18    }

Heartbeat alarm is derived from Alarm. I am getting a compile error "cannot implicitly convert type...An explicit conversion exists (are you missing a cast?)". How do I set this up to return a derived type?

EDIT

THANK YOU ALL FOR YOUR ANSWERS. I fixed the compile error within ten minutes which is why i did not post the whole error. But I appreciated the different approaches that were mentioned.

For the record it was "Cannot implicitly convert type 'goAlarmsCS.HeartbeatAlarm' to 'goAlarmsCS.Alarm' An explicit conversion exists (are you missing a cast?)". (I think.) The error was occurring on line 8.

Seth

Was it helpful?

Solution

Below is a solution that includes a specific GetHeartbeatAlarm function to retrieve a HeartbeatAlarm object as well as a generic GetAlarm function to return an alarm whose type is determined by the generic parameter. At the bottom there is some example code showing how this would be called:

enum AlarmTypes
{
    Heartbeat,
    AnotherAlarm,
    // ...
}

delegate void CreateTriggerDelegate();

class Alarm
{
    // ...

    public CreateTriggerDelegate CreateTriggerFunction { get; set; }
}

class HeartbeatAlarm : Alarm
{
    // ...

    public static HeartbeatAlarm GetAlarm()
    {
        return new HeartbeatAlarm();
    }
}

class QuartzAlarmScheduler
{
    public static CreateTriggerDelegate CreateMinutelyTrigger { get; set; }
}

class AlarmFactory
{
    public static Alarm GetAlarm(AlarmTypes alarmType)  //factory ensures that correct alarm is returned and right func pointer for trigger creator.
    {
        switch (alarmType)
        {
            case AlarmTypes.Heartbeat:
                return GetHeartbeatAlarm();
            default:
                throw new ArgumentException("Unrecognized AlarmType: " + alarmType.ToString(), "alarmType");
        }
    }

    static Alarm _GetAlarm<T>()
        where T : Alarm
    {
        Type type = typeof(T);
        if (type.Equals(typeof(HeartbeatAlarm)))
            return GetHeartbeatAlarm();
        else
            throw new ArgumentException("Unrecognized generic Alarm argument: " + type.FullName, "T");
    }

    public static T GetAlarm<T>()
        where T : Alarm
    {
        return (T)_GetAlarm<T>();
    }

    public static HeartbeatAlarm GetHeartbeatAlarm()
    {
        HeartbeatAlarm alarm = HeartbeatAlarm.GetAlarm();
        alarm.CreateTriggerFunction = QuartzAlarmScheduler.CreateMinutelyTrigger;
        return alarm;
    }
}

class Example
{
    static void GetAlarmExamples()
    {
        HeartbeatAlarm alarm;

        alarm = AlarmFactory.GetHeartbeatAlarm();

        alarm = AlarmFactory.GetAlarm<HeartbeatAlarm>();

        alarm = (HeartbeatAlarm)AlarmFactory.GetAlarm(AlarmTypes.Heartbeat);
    }
}

OTHER TIPS

Your best bet would be to make Alarm an interface, or if that's not possible, create an IAlarm interface, and inherit from this interface for both Alarm and HeartbeatAlarm.

AlarmFactory.GetAlarm should return an IAlarm instance. Likewise, HeartbeatAlarm.GetAlarm() should return an IAlarm instance.

This should eliminate any compiler errors, plus the upside is that all relationships are cleanly contractual, which should make the code that much more future-friendly.

Have you tried what the compiler suggests?

return (Alarm) alarm;

Edit: This is completely wrong, but I'm leaving this answer here to preserve the discussion in the comments.

As some have already suggested, a redundant Interface is an easy way to accomplish this. Seems like a clean example might help future visitors..

public interface IAlarm
{
    public int bpm { get; set; }    // declared base props
}

public class Alarm : IAlarm
{
    public int bpm { get; set; }    // implemented base props
}

public class HeartbeatAlarm : Alarm
{
    public int min { get; set; }    // extended type specific props
}

public class FactoryMethods
{
    public static T AlarmFactory<T>(int bpm) where T : IAlarm, new()
    {
        // interfaces have no constructor but you can do this
        T alarm = new T() {
            bpm = bpm
        };

        return alarm;
    }
}

// C# will automagically infer the type now..
HeartbeatAlarm heartbeatAlarm = FactoryMethods.AlarmFactory<HeartbeatAlarm>(40);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top