首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >为什么Animals[] Cat[5] =新Cat[5]编译,而List<Animal> List<Cat>=新List<Cat>()不编译?

为什么Animals[] Cat[5] =新Cat[5]编译,而List<Animal> List<Cat>=新List<Cat>()不编译?
EN

Stack Overflow用户
提问于 2011-09-28 19:01:48
回答 3查看 607关注 0票数 6

乔恩·斯基特在他的著作“深度的C#”中试图回答以下问题:

为什么我不能将List<string>转换为List<object>

为了解释这一点,他从一个代码片段开始,其中包括以下两行:

代码语言:javascript
复制
Animal[] animals = new Cat[5]; //Ok. Compiles fine!            
List<Animal> animals = new List<Cat>(); //Compilation error!

正如注释所述,第一个是编译精细,第二个是编译错误。我不太明白原因。Jon解释了这一点,只说第一个是因为在.NET中数组是协变的,而第二个是不编译的,因为泛型不是协变的(相反,它们是不变的)。而且,数组在.NET中是协变的,因为数组在Java中是协变的,而.NET使其类似于Java。

我对这个简短的答案并不完全满意。我想更详细地了解它,了解编译器是如何处理这种差异的,以及它是如何生成IL和all的。

此外,如果我写(摘自这本书本身):

代码语言:javascript
复制
Animal[] animals = new Cat[5]; //Ok. Compiles fine!
animals.Add(new Turtle()); //this too compiles fine!

它编译得很好,但在运行时失败了。如果它必须在运行时失败(这意味着我写的东西没有意义),那么为什么它首先要编译呢?我是否可以在代码中使用实例animals,并且运行时也没有错误?

EN

回答 3

Stack Overflow用户

发布于 2011-09-28 19:06:11

数组在.NET中有一个奇怪的变化历史,在CLR的2.0版本和C# 4.0中添加了对方差的适当支持。然而,数组始终具有协变行为。

Eric在博客帖子中详细介绍了这一点。

有趣的一点是:

从C# 1.0开始,元素类型是引用类型的数组是协变量的。这是完全合法的: Animal[]动物=新Giraffe10; 由于长颈鹿比动物小,并且“make a array”是类型上的协变操作,所以Giraffe[]比Animal[]小,所以实例适合这个变量。 不幸的是,这种特殊的协方差被打破了。它被添加到CLR中,因为Java需要它,而CLR设计人员希望能够支持类似Java的语言。然后,我们将其添加到C#中,因为它位于CLR中。这个决定当时很有争议,我对此不太高兴,但我们现在无能为力。

我自己加的重点。

票数 10
EN

Stack Overflow用户

发布于 2011-09-28 19:54:11

如果它必须在运行时失败,那么为什么它首先要编译?

这正是数组协方差被打破的原因。事实上,我们允许它意味着我们允许在编译时被捕获的错误被忽略,而在运行时被捕获。

我对这个简短的答案并不完全满意。我想更详细地了解它,并深入了解编译器如何处理这种差异.

编译器非常容易地处理这种差异。编译器有大量的代码来确定一种类型何时与另一种类型兼容。该代码的一部分处理数组到数组的转换。该代码的一部分处理泛型到泛型转换。代码是规范相关行的直接转换。

..。以及它是如何产生IL和所有的。

没有必要为协变数组转换生成任何IL。为什么我们需要为两个兼容引用的类型之间的转换生成IL?--这就像问我们为将字符串转换为对象所生成的IL是什么。字符串已经是一个对象,因此没有生成任何代码。

票数 7
EN

Stack Overflow用户

发布于 2011-09-28 19:16:12

我认为consider解释得相当好,但是如果您需要"Ahah“这个时刻,请考虑泛型是如何工作的。

在大多数情况下,像List<>这样的泛型类在外部被视为一个普通类。例如,当您说List<string>()时,编译器表示ListString() (它包含字符串),编译器不能聪明地通过转换其内部集合的项将ListString转换为ListObject。

从阅读MSDN博客文章可以看出,在使用委托和接口时,.NET 4.0支持协方差和反向方差。它还在第二句中提到Eric的文章。

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

https://stackoverflow.com/questions/7588183

复制
相关文章

相似问题

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