gpt4 book ai didi

c# - 为什么 Animals[] animals = new Cat[5] 编译,但 List animals = new List() 不编译?

转载 作者:太空狗 更新时间:2023-10-29 20:53:20 28 4
gpt4 key购买 nike

在他的C# 深入一书中,Jon Skeet 试图回答以下问题:

Why can't I convert List<string> to List<object>?

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

Animal[] animals = new Cat[5]; //Ok. Compiles fine!            
List<Animal> animals = new List<Cat>(); //Compilation error!

正如评论所读,第一个compiles fine , 但第二个给出 compilation error .我真的不明白原因。 Jon Skeet 对此解释说,第一个编译是因为在 .NET 中,数组是协变的,而第二个不编译是因为泛型不是协变的(它们是不变的)。此外,数组在 .NET 中是协变的,因为数组在 Java 中是协变的,而 .NET 使其类似于 Java。

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

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

Animal[] animals = new Cat[5]; //Ok. Compiles fine!
animals.Add(new Turtle()); //this too compiles fine!

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

最佳答案

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

Eric Lippert 在 blog post 中详细介绍了这一点.

有趣的一点:

Ever since C# 1.0, arrays where the element type is a reference type are covariant. This is perfectly legal:

Animal[] animals = new Giraffe[10];

Since Giraffe is smaller than Animal, and “make an array of” is a covariant operation on types, Giraffe[] is smaller than Animal[], so an instance fits into that variable.

Unfortunately, this particular kind of covariance is broken. It was added to the CLR because Java requires it and the CLR designers wanted to be able to support Java-like languages. We then up and added it to C# because it was in the CLR. This decision was quite controversial at the time and I am not very happy about it, but there’s nothing we can do about it now.

强调是我自己加的。

关于c# - 为什么 Animals[] animals = new Cat[5] 编译,但 List<Animal> animals = new List<Cat>() 不编译?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7588183/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com