【发布时间】:2019-10-28 14:37:40
【问题描述】:
我有以下对象架构:
public interface IConfigAlarmBase{}
public interface IConfigAlarmBinary:IConfigAlarmBase{}
public interface IConfigAlarmRanged:IConfigAlarmBase{}
public interface IAlarmItem<TConfig> where TConfig : IConfigAlarmBase{}
public abstract class AlarmItemBase<TConfig> : IAlarmItem<TConfig> where TConfig :IConfigAlarmBase {}
public abstract class AlarmItemBinaryBase:AlarmItemBase<IConfigAlarmBinary>{}
public abstract class AlarmItemRangedBase<TConfig> : AlarmItemBase<TConfig> where TConfig:IConfigAlarmRanged{}
public class AlarmImplementation:AlarmItemRangedBase<IConfigAlarmRanged>
还有一些AlarmItemBinaryBase 对象及其兄弟AlarmItemRangedBase 的实现。
我想将所有警报存储在一个列表中,该列表定义为:List<IAlarmItem<IConfigAlarmBase>>
但是当我实例化我的列表并尝试填充它时,我得到一个错误:
System.InvalidCastException: Unable to cast object of type 'Alarm.Implementations.AlarmImplementation' to type 'Common.Application.Alarm.IAlarmItem`1[Common.Config.Alarms.IConfigAlarmBase]'.
我不明白AlarmImplementation 是IAlarmItem 的实现(通过AlarmItemRangedBase 的类层次结构),而IConfigAlarmRanged 是IConfigAlarmBase 的子代。对我来说,这应该是一种失望,因为所有的类都派生自 Base 类。
但看来我错了。当编译器替换模板时,是否有可能将泛型类型视为特定类型而忽略模板化类型之间的关系?
感谢您对这个问题的所有考虑。
【问题讨论】:
-
阅读协方差 - 有很多类似的问题。
-
“当编译器替换模板时”——它们不会发生这样的事情。如果您认为 .NET 泛型是 C++ 的不同名称的模板,那么您将犯错误。它们有相似之处,但也有不同。
-
@Damien_The_Unbeliever:谢谢你的提示,我确实这么认为。我会更加努力地研究它。
标签: c#