我已经创建了一个名为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 }
心跳警报来自警报。我收到编译错误“无法隐式转换类型...存在显式转换(你是否错过了演员?)”。如何设置它以返回派生类型?
修改
谢谢你的回答。我在十分钟内修复了编译错误,这就是我没有发布整个错误的原因。但我很欣赏所提到的不同方法。
对于记录,它是“无法将类型'goAlarmsCS.HeartbeatAlarm'隐式转换为'goAlarmsCS.Alarm'存在显式转换(您是否错过了转换?)”。 (我想。)错误发生在第8行。
赛斯
答案 0 :(得分:4)
下面是一个解决方案,其中包含用于检索HeartbeatAlarm对象的特定GetHeartbeatAlarm函数以及用于返回类型由泛型参数确定的警报的通用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);
}
}
答案 1 :(得分:3)
您最好的选择是使Alarm
成为一个接口,或者如果不可能,则创建一个IAlarm
接口,并继承Alarm
和{{1}的此接口}。
HeartbeatAlarm
应返回AlarmFactory.GetAlarm
个实例。同样,IAlarm
应返回HeartbeatAlarm.GetAlarm()
个实例。
这应该消除任何编译器错误,而且好处是所有关系都是完全契约的,这应该使代码更加适合未来。
答案 2 :(得分:0)
您是否尝试过编译器建议的内容?
return (Alarm) alarm;
编辑:这是完全错误的,但我在这里留下这个答案以保留评论中的讨论。
答案 3 :(得分:0)
正如一些人已经建议的那样,冗余接口是实现这一目标的简单方法。看起来像一个干净的例子可能会帮助未来的访客..
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);