【问题标题】:C# : Downcasting Generic object with derived interfaces to the base interfaceC#:将具有派生接口的通用对象向下转换为基接口
【发布时间】: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&lt;IAlarmItem&lt;IConfigAlarmBase&gt;&gt;

但是当我实例化我的列表并尝试填充它时,我得到一个错误:

System.InvalidCastException: Unable to cast object of type 'Alarm.Implementations.AlarmImplementation' to type 'Common.Application.Alarm.IAlarmItem`1[Common.Config.Alarms.IConfigAlarmBase]'.

我不明白AlarmImplementationIAlarmItem 的实现(通过AlarmItemRangedBase 的类层次结构),而IConfigAlarmRangedIConfigAlarmBase 的子代。对我来说,这应该是一种失望,因为所有的类都派生自 Base 类。

但看来我错了。当编译器替换模板时,是否有可能将泛型类型视为特定类型而忽略模板化类型之间的关系?

感谢您对这个问题的所有考虑。

【问题讨论】:

  • 阅读协方差 - 有很多类似的问题。
  • “当编译器替换模板时”——它们不会发生这样的事情。如果您认为 .NET 泛型是 C++ 的不同名称的模板,那么您将犯错误。它们有相似之处,但也有不同。
  • @Damien_The_Unbeliever:谢谢你的提示,我确实这么认为。我会更加努力地研究它。

标签: c#


【解决方案1】:

您的列表是List&lt;IAlarmItem&lt;IConfigAlarmBase&gt;&gt;,并且您尝试添加AlarmItemRangedBase&lt;IConfigAlarmRanged&gt;,因此即使IConfigAlarmRanged 继承自IConfigAlarmBase,您也存在类型不匹配,因为IAlarmItem&lt;IConfigAlarmBase&gt;IAlarmItem&lt;IConfigAlarmRanged&gt; 不是同一类型:它们是两种不同的封闭构造泛型类型,您不能从一种类型转换为另一种类型。

例如,List&lt;string&gt;List&lt;int&gt; 是不同的类型,它们之间没有层次结构,也没有可用的侧向转换。

Generics -Open and closed constructed Types

About the lack of true generic polymorphism and the missing diamond operator in C#

【讨论】:

  • 它确实回答了我的问题,我想你用更简单的词表达了我的意思。谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-08-30
  • 2010-12-12
  • 2016-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多