首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么C#阵列是协变的,它带来了什么好处?

为什么C#阵列是协变的,它带来了什么好处?
EN

Stack Overflow用户
提问于 2010-08-19 04:57:15
回答 3查看 596关注 0票数 8

我很难理解为什么C#中的数组是协变的,以及这种协变能带来什么好处。考虑下面这个简单的代码示例:

代码语言:javascript
运行
复制
object[] myArray = new string[1];
myArray[0] = 1;

这段代码可以正常编译,但会在运行时突然爆炸,这也许并不令人意外。

如果我尝试使用泛型做同样的事情,编译器会对我发牢骚,我会在早期阶段意识到我的愚蠢,所以我的问题是:为什么C#编译器允许数组的这种协变,而且,潜在的好处是什么?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-08-19 04:59:49

Eric Lippert说:

不幸的是,这种特殊的协方差被打破了。之所以将它添加到CLR中,是因为Java需要它,而CLR设计者希望能够支持类似Java的语言。然后,我们将其添加到C#中,因为它在CLR中。这一决定在当时很有争议,我对此并不是很高兴,但现在我们对此无能为力。

票数 13
EN

Stack Overflow用户

发布于 2010-08-19 04:59:30

Eric Lippert有一篇关于这方面的文章(实际上是关于‘方差’的一个很长的系列,我认为是11部分)

http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx

还有一些更有趣的东西

http://blogs.msdn.com/b/ericlippert/archive/2009/09/24/why-is-covariance-of-value-typed-arrays-inconsistent.aspx

票数 4
EN

Stack Overflow用户

发布于 2013-07-16 02:23:00

在许多情况下,代码将在数组的插槽之间移动或复制项。如果Arr是至少包含两个元素的一维数组,则无论Arr的类型或其中包含的元素是什么,下面的代码都可以工作。

代码语言:javascript
运行
复制
Object temp = Arr[1];
Arr[1] = Arr[0];
Arr[0] = temp;

如果Arr是一个值类型,那么这个代码的效率会很低,但是因为temp是从数组中读出的,所以可以保证数组的类型能够保存这样的值。代码将不得不装箱和拆箱值类型的元素,因此对于这种类型的效率将很低,但它仍然可以工作。

请注意,虽然使数组协变是允许排序方法在任意数组类型上工作的一种方法,但这并不是唯一的方法。另一种方法是让System.Array包含一些方法和属性,这些方法和属性的参数与底层元素类型无关。例如,它可以包括一些简单的方法,如SwapCopyItemRoll,还可能包括在给定一系列索引的情况下执行更复杂的排列的方法。请注意,与上面显示的代码不同,像Int[]这样的类型可以通过某种方式重写其Swap方法,以避免装箱和取消装箱。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3516619

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档