【问题标题】:List<T> inheritance behaves strangely [duplicate]List<T> 继承行为奇怪[重复]
【发布时间】:2012-12-10 14:29:19
【问题描述】:

可能重复:
C# variance problem: Assigning List<Derived> as List<Base>

我遇到了列表继承问题。看起来具有更多指定成员的通用列表无法转换为具有其基本成员的列表。 看看这个:

class A
{
    public int aValue {get; set;}
}

class B : A
{
    public int anotherValue {get; set;}
}

您现在可能认为List&lt;B&gt; 也是List&lt;A&gt;,但事实并非如此。 List&lt;A&gt; myList = new List&lt;B&gt;() 是不可能的。甚至List&lt;A&gt; myList = (List&lt;A&gt;)new List&lt;B&gt;() 在面向对象编程工作 3 年后,我是否在这里遗漏了一些基本概念?

【问题讨论】:

  • 泛型在 .NET 中的工作方式
  • 这就是协方差在 .NET 中对于泛型的工作方式。您必须创建一个中间接口。不久前我有same question

标签: c# list generics inheritance


【解决方案1】:

是的!

假设你可以做到

List<A> myList = new List<B>();

然后假设你有一个类

class C : A { public int aDifferentValue { get; set; } }

CA,因此您希望能够调用 myList.Add(new C()),因为 myList 认为它是 List&lt;A&gt;

但是C 不是B,所以myList - 真的 List&lt;B&gt; - 不能容纳C


相反,假设你可以这样做

List<B> myList = new List<A>();

您可以愉快地调用myList.Add(new B()),因为BA

但假设有其他东西在您的列表中添加了C(因为CA)。

那么myList[0] 可能会返回C - 这不是B

【讨论】:

  • List&lt;B&gt; myList = new List&lt;A&gt;() 不起作用,因为不是每个 A 也是 B。B obj = new A() 也不起作用。但是,如果C : A,为什么List&lt;B&gt; 不能持有C?我的意思是,我不能调用C 特定的方法,但至少可以做任何我可以用A 做的事情。
  • @David 因为你可以用A 做任何你能做的事情,你可以把C 放在List&lt;A&gt; 中,但是你不能做所有你可以用@ 做的事情987654353@ 所以你不能把它放在List&lt;B&gt; 中。
【解决方案2】:

不允许简单的转换 现在使用

List<B> lb = new List<B> { ... };
List<A> la = lb.Cast<A>().ToList();

【讨论】:

  • "c# 5.0 将允许": 不,C# 5.0 不允许。
  • it will be allowed in c# 5.0 不会。
  • 您对此有什么好的参考吗? C# 5 在 .Net 4.5 中,因此发布...
猜你喜欢
  • 1970-01-01
  • 2018-06-04
  • 1970-01-01
  • 2011-07-19
  • 1970-01-01
  • 2012-11-08
  • 1970-01-01
  • 1970-01-01
  • 2020-08-06
相关资源
最近更新 更多