列表,数组和IEnumerable协方差 [英] List, array and IEnumerable covariance
问题描述
我会与几个公设开始更好地解释我的问题的背景:
阵列协方差
假定1.1
值类型的数组是不是协变。 INT []
不能通过为 [对象]
。
假设1.2
引用类型的数组是协变的一个有效的的IEnumerable
。 的String []
可以通过为的IEnumerable<对象>
)
假设1.3
引用类型的数组是协变的一个有效的协变数组。 的String []
可以通过为 [对象]
。
列表协方差
假设2.1(同1.1)
值类型的列表不是协变的。 列表< INT>
不能通过为列表<对象>
假设2.2(同1.2)
引用类型的列表是协变的一个有效的的IEnumerable
。 列表<串>
可以通过为的IEnumerable<对象>
)
假定2.3(不同于1.3)
引用类型的列表不是一个有效的协变协变列表
。 列表<串>
不能通过为列表<对象>
)
我的问题的担忧假定1.3,2.2和2.3。具体做法是:
- 为什么
的String []
通为[对象]
,但列表<串&GT ;
不是列表<对象>
- 为什么
列表<串>
通为的IEnumerable<对象>
而不是清单<对象>
清单协方差是不安全的:
列表<串GT;串=新的List<串GT; {一,B,C};
清单<对象>对象=串;
objects.Add(1); //
阵列协方差也是不安全出于同样的原因:
的String [] =串新的[] {A,B,C};
对象[]对象=串;
对象[0] = 1; //抛出ArrayTypeMismatchException
在C#中的数组协方差是公认的<一个href=\"http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx\">as一个错误,并已present从版本1。
由于集合无法通过的IEnumerable&LT进行修改; T&GT;
接口,它是安全的键入列表&LT;串&GT;
为的IEnumerable&LT;对象&gt;
I'll start with several postulates to better explain the context of my question:
Array Covariance
Postulate 1.1
An array of a value type is not covariant. int[]
cannot pass for object[]
.
Postulate 1.2
An array of a reference type is covariant with a valid IEnumerable
. string[]
can pass for IEnumerable<object>
).
Postulate 1.3
An array of a reference type is covariant with a valid covariant array. string[]
can pass for object[]
.
List Covariance
Postulate 2.1 (same as 1.1)
A list of a value type is not covariant. List<int>
cannot pass for List<object>
.
Postulate 2.2 (same as 1.2)
A list of a reference type is covariant with a valid IEnumerable
. List<string>
can pass for IEnumerable<object>
).
Postulate 2.3 (different from 1.3)
A list of a reference type is not covariant with a valid covariant List
. List<string>
cannot pass for List<object>
).
My question concerns postulates 1.3, 2.2 and 2.3. Specifically:
- Why can
string[]
pass forobject[]
, butList<string>
not forList<object>
? - Why can
List<string>
pass forIEnumerable<object>
but not forList<object>
?
List covariance is unsafe:
List<string> strings = new List<string> { "a", "b", "c" };
List<object> objects = strings;
objects.Add(1); //
Array covariance is also unsafe for the same reason:
string[] strings = new[] { "a", "b", "c" };
object[] objects = strings;
objects[0] = 1; //throws ArrayTypeMismatchException
array covariance in C# is recognised as a mistake, and has been present since version 1.
Since the collection cannot be modified through the IEnumerable<T>
interface, it is safe to type a List<string>
as an IEnumerable<object>
.
这篇关于列表,数组和IEnumerable协方差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!