为什么以下代码不起作用?
class parent {}
class kid:parent {}
List<parent> parents=new List<kid>;
对我来说这似乎很明显。这是怎么回事?
答案 0 :(得分:10)
C#目前不支持covariance。
然而,在.NET 4.0中,它是coming在接口和委托上。
Eric Lippert在他的博客上有一段非常好的series。 Visual Studio Magazine在最近的article中也涵盖了这一点。
答案 1 :(得分:4)
除了在版本4.0之前的C#中缺少通用差异支持,List是可变的,因此不能安全地协变。考虑一下:
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?
}
这会尝试将Parent添加到通过List引用引用的List,这是不安全的。允许数组由运行时协变,但在突变时进行类型检查,如果新元素不能分配给数组的运行时元素类型,则抛出异常。
答案 2 :(得分:2)
您正在寻找的功能称为协方差。在版本4.0之前的C#中不支持它,然后仅在接口和委托上支持它。
有关该主题的一些链接
答案 3 :(得分:1)
如果您知道List<Parent>
包含List<child>
,您可以使用扩展方法来“转换”,(实际上只需将父类型为子类型并将其返回列表中。例如像:
public static List<T> Convert<T, T2>(this List<T2> input) {
return input.OfType<T>().ToList();
}
我不确定这对你有帮助,但我的价值2美分!我用的很多。
答案 4 :(得分:0)
正如已经指出的那样,C#目前不支持。在Java中,数组是协变的,它可能会导致一些问题。考虑一下你的例子,实际的列表应该是一个“kid”列表,这意味着它中的所有对象都应该是“kid”(或“孙子”)。但是,如果您用于访问列表的引用是“父”列表,那么您可以在列表中插入“父”,这显然不应该发生。