【问题标题】:C# inheritance in generics question泛型问题中的 C# 继承
【发布时间】:2010-11-10 16:42:29
【问题描述】:

我有两个接口:

public interface A { 
 void aMethod(); 
}


public interface B : A {
 void bMethod();
} 

后来我基本上用的是这样的字典:

Dictionary<int, A> dict = new Dictionary<int, B>();

C# 说我不能从右向左转换,即使我施放它。有没有办法在 C# 中使用泛型以便它可以工作?如果我将它们设为抽象类似乎没问题,但我需要这些作为接口。

【问题讨论】:

  • 您使用的是什么版本的 .NET?
  • @Dinah:为什么框架版本在这种情况下会有什么不同?
  • @LukeH:因为 .NET 4.0 具有协方差和反方差,可以解决这个问题。如果 dmurph 在 4.0 上仍存在此问题,则该问题与 4.0 之前发生的问题不同
  • @Dinah:C#4 引入了泛型接口和委托的变体,not 类,因此如果尝试将 Dictionary&lt;int, B&gt; 分配给 Dictionary&lt;int, A&gt; 没有区别.
  • 看来我什至没有使用 4.0。这里的每个人看起来都是正确的......

标签: c# generics inheritance


【解决方案1】:

您正在寻找的特性是所谓的泛型方差(协方差和逆变)。从 .net 框架 4 开始,对此的支持有限。这是一篇有趣的帖子:How is Generic Covariance & Contra-variance Implemented in C# 4.0?

这是MSDN entry on Covariance and Contravariance in Generics

【讨论】:

  • 感谢 msdn 链接,这很有帮助,看来我必须以其他方式解决我的问题
【解决方案2】:

不,这是协方差问题。如果可以的话:

Dictionary<int, A> dict = new Dictionary<int, B>();

将类型 A 的对象放入 dict 中是可能的而不会出现编译器错误。

问题是 dict 看起来像:Dictionary&lt;int, A&gt; 但它实际上是类型 Dictionary&lt;int, B&gt;() (因此放置类型 A 的对象会因为无效的强制转换而引发运行时错误),所以你不应该被允许甚至尝试将类型 A 的对象放在 dict 中,这就是为什么你不能这样做:

Dictionary<int, A> dict = new Dictionary<int, B>();

它可以保护您避免出现运行时错误。
您想查看 Eric Lippert 关于该主题的博客:Link

这是他最喜欢谈论的话题之一,所以说得很透彻。

【讨论】:

    【解决方案3】:

    我不认为你会找到解决问题的方法,因为它背后的想法似乎有缺陷。为了说明,让我们创建另一个接口:

    public interface C : A
    {
        void cMethod();
    }
    

    现在,让我们使用您的代码:

    Dictionary<int, A> dict = new Dictionary<int, B>();
    

    当我尝试以下操作时会发生什么?

    C c = new ClassThatImplementsC(); 
    dict.Add(1, c);
    

    查看Eric Lippert's Covariance and Contravarience FAQ 了解更多详细信息。

    【讨论】:

      猜你喜欢
      • 2011-08-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-05-01
      相关资源
      最近更新 更多