2013-10-13 38 views
1

我在想:为什么阵列不是逆变?

从C#4.0开始,通用接口允许协变(与通用委托4类似),但泛型类不允许。

阵列支持协方差(S []可转换为B []若S子类B)

因此,它是完全有效的做到这一点:

string[] obj = new string[3]; 
     obj[0]="1"; 
     obj[1]="2"; 
     obj[2]="3"; 

Do something with : (obj as object[]) 
Do something with : (object[])obj ... 
Do something with : ((IEnumerable<object>)obj) 

这种可重用性的缺点是元素分配可能在运行时失败

(obj as object[])[0] = new DateTime(); //errrr... 

好的 - 它可能会失败。

所以如果在运行时它已经失效了(这是由我来检查它),为什么他们不把它也作为contravariant

 object[] obj = new object[3]; 
     obj[0]="1"; 
     obj[1]="2"; 
     obj[2]="3"; 

这样我就能做到(我的责任):

(obj as string[])... 
+0

所以你想能够写'(字符串[])(object [])new Button [5]'? – SLaks

+0

@SLaks我们知道这里有一个问题(运行时)。我只是说,如果它是由我来检查类型 - 为什么他们没有使它也是逆变的,以便我能够使用它从另一种方式。 –

+1

这不是C#1.0只是复制Java所做的事情吗? – dtb

回答

3

这已经够糟糕,他们让协方差,因为那时每次你写一个数组,即设置一个其元素添加到新的参考中,则必须执行类型检查。

如果它们也允许反转,那么数组中的每个读取也需要类型检查。那会更糟。

在过去的.NET阵列经常通过的地方,预计接收器只能从读取阵列。那么“疯狂”的协变有点意义。逆变并没有那么有用。