[英]List, array and IEnumerable covariance
I'll start with several postulates to better explain the context of my question: 我将从几个假设开始,以更好地解释我的问题的背景:
An array of a value type is not covariant. 值类型的数组不是协变的。
int[]
cannot pass for object[]
. int[]
无法传递object[]
。
An array of a reference type is covariant with a valid IEnumerable
. 引用类型的数组与有效的
IEnumerable
协变。 string[]
can pass for IEnumerable<object>
). string[]
可以传递给IEnumerable<object>
。
An array of a reference type is covariant with a valid covariant array. 引用类型的数组与有效的协变数组协变。
string[]
can pass for object[]
. string[]
可以传递给object[]
。
A list of a value type is not covariant. 值类型的列表不是协变的。
List<int>
cannot pass for List<object>
. List<int>
无法传递List<object>
。
A list of a reference type is covariant with a valid IEnumerable
. 引用类型的列表与有效的
IEnumerable
协变。 List<string>
can pass for IEnumerable<object>
). List<string>
可以传递给IEnumerable<object>
。
A list of a reference type is not covariant with a valid covariant List
. 引用类型列表与有效协变
List
不协变。 List<string>
cannot pass for List<object>
). List<string>
无法传递List<object>
)。
My question concerns postulates 1.3, 2.2 and 2.3. 我的问题涉及假设1.3,2.2和2.3。 Specifically:
特别:
string[]
pass for object[]
, but List<string>
not for List<object>
? string[]
传递给object[]
,但是List<string>
不能传递给List<object>
? List<string>
pass for IEnumerable<object>
but not for List<object>
? List<string>
传递IEnumerable<object>
而不能传递给List<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. C#中的数组协方差被认为是一个错误 ,并且自版本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<T>
接口修改集合,因此可以安全地将List<string>
键入为IEnumerable<object>
。
Arrays are covariant, but a System.Int32[]
does not hold references to things which are derived from System.Object
. 数组是协变的,但
System.Int32[]
不保存对从System.Object
派生的内容的引用。 Within the .NET runtime, each value-type definition actually defines two kinds of things: a heap object type and a value (storage location) type. 在.NET运行时中,每个值类型定义实际上定义了两种类型:堆对象类型和值(存储位置)类型。 The heap object type is derived from
System.Object
; 堆对象类型派生自
System.Object
; the storage location type is implicitly convertible to the heap object type (which in turn derives from System.Object
) but does not itself actually derive from System.Object
nor anything else. 存储位置类型可以隐式转换为堆对象类型(后者又从
System.Object
派生)但实际上并不是从System.Object
派生的,也不是其他任何东西。 Although all arrays, including System.Int32[]
are heap-object types, the individual elements of a System.Int32[]
are instances of the storage location type. 尽管所有数组(包括
System.Int32[]
都是堆对象类型),但System.Int32[]
的各个元素都是存储位置类型的实例。
The reason that a String[]
can be passed to code expecting an Object[]
is that the former contains "references to heap-object instances of type derived from type String
", and the latter likewise for type Object
. 可以将
String[]
传递给期望Object[]
代码的原因是前者包含“对从类型String
派生的类型的堆对象实例的引用”,后者同样适用于类型Object
。 Since String
derives from Object
, a reference to a heap-object of a type derived from String
will also be a reference to a heap object which derives from Object
, and a String[]
will contain references to heap objects which derive from Object
--exactly what code would expect to read from an Object[]
. 由于
String
从导出Object
,从派生的类型的一个堆对象的引用String
也将是从派生的堆对象的引用Object
,和一个String[]
将包含对从派生堆中的对象的引用Object
-究竟是什么代码期望从Object[]
读取。 By contrast, because an int[]
[ie System.Int32[]
] does not contain references to heap-object instances of type Int32
, its contents will not conform to the expectations of code which is expecting Object[]
. 相反,因为
int[]
[即System.Int32[]
]不包含对Int32
类型的堆对象实例的引用,所以它的内容将不符合期望Object[]
的代码的期望。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.