列表,数组和IEnumerable协方差 [英] List, array and IEnumerable covariance

查看:156
本文介绍了列表,数组和IEnumerable协方差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会与几个公设开始更好地解释我的问题的背景:

阵列协方差

假定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。具体做法是:


  1. 为什么的String [] 通为 [对象] ,但列表<串&GT ; 不是列表<对象>

  2. 为什么列表<串> 通为的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:

  1. Why can string[] pass for object[], but List<string> not for List<object>?
  2. Why can List<string> pass for IEnumerable<object> but not for 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.

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆