为什么不能列出 =名单 ?(Why can't List = Li

2019-06-26 14:25发布

为什么不将下面的代码工作?

class parent {}
class kid:parent {}

List<parent> parents=new List<kid>;

这似乎是显而易见的我。 这里发生了什么?

Answer 1:

C#目前不支持协方差 。

它的未来在.NET 4.0中,然而,在接口和委托。

埃里克利珀有一个非常漂亮的一系列在他的博客这个问题一段时间回来。 Visual Studio的杂志涵盖太在最近的文章 。



Answer 2:

除了缺乏之前4.0版C#泛型支持方差,列表是可变的,所以无法安全地协变。 试想一下:

void AddOne<T>(List<T> arg) where T : new()
{
    arg.Add(new T());
}

void Whoops()
{
    List<parent> contradiction = new List<kid>();
    AddOne(contradiction);  // what should this do?
}

这将试图父添加到通过列表的参考,这是不是安全的引用的列表。 允许阵列由运行时协变,但类型检查的突变时间,如果新元素是不能分配给数组的运行时元素类型的异常被抛出。



Answer 3:

您正在寻找的功能称为协方差。 这是不是在C#只能在接口和代表支持,直到4.0版本,然后。

关于这个问题的一些链接

  • http://visualstudiomagazine.com/articles/2009/05/01/generic-covariance-and-contravariance-in-c-40.aspx
  • http://msdn.microsoft.com/en-us/library/ms173174(VS.80).aspx


Answer 4:

如果您知道List<Parent>包含List<child>您可以使用扩展方法来“转换”,(其实只是采取的类型是孩子的父母,并在列表中返回他们如像:

  public static List<T> Convert<T, T2>(this List<T2> input) {
      return input.OfType<T>().ToList();
    }

林不知道如果这能帮助你,但我的2美分的价值! 我用它相当很多。



Answer 5:

正如已经指出的那样,这是当前不支持C#。 在Java中,数组是协变的,它可能会导致一些问题。 考虑你的例子,实际的名单应该是“孩子”的名单,这意味着在它所有的对象应该是“孩子” S(或“孙子”)。 但是,如果你正在使用访问列表中引用的“父”的列表,那么你可以插入一个“父”到这显然是不应该发生的列表。



文章来源: Why can't List = List?