我创建了一个称为AlarmFactory的工厂类...

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    }

心跳警报来自警报。我遇到了一个编译错误“无法隐式转换类型...存在明确的转换(您缺少演员?)。”我如何设置此设置以返回派生类型?

编辑

谢谢大家的答案。我在十分钟内修复了编译错误,这就是为什么我没有发布整个错误的原因。但是我感谢提到的不同方法。

作为记录,它是“不能隐式将类型的'grogarmscs.heartbeatalarm'转换为'grogarmscs.s.alarm'存在明确的转换(您是否缺少演员?)”。 (我认为)错误发生在第8行。

塞思

有帮助吗?

解决方案

下面是一个解决方案,其中包含特定的geartbeatAlarm函数,以检索HeartBeatAlarm对象以及通用的GetAlarm函数,以返回由通用参数确定的类型的警报。在底部有一些示例代码,显示了如何调用:

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);
    }
}

其他提示

最好的选择是 Alarm 接口,或者如果不可能,则创建一个 IAlarm 接口,并从此接口继承 AlarmHeartbeatAlarm.

AlarmFactory.GetAlarm 应该返回 IAlarm 实例。同样地, HeartbeatAlarm.GetAlarm() 应该返回 IAlarm 实例。

这应该消除任何编译器错误,再加上所有关系是所有关系都是干净的合同,这应该使代码变得更加友好。

您是否尝试过编译器的建议?

return (Alarm) alarm;

编辑:这是完全错误的,但是我在这里留下了这个答案,以保留评论中的讨论。

正如某些人已经提出的那样,冗余界面是实现此目的的一种简单方法。似乎一个干净的例子可能会帮助未来的访客。

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);
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top