gpt4 book ai didi

c# - 为什么数组协方差被认为如此可怕?

转载 作者:可可西里 更新时间:2023-11-01 07:50:22 25 4
gpt4 key购买 nike

在 .NET 中,引用类型数组是协变的。这被认为是一个错误。但是,我不明白为什么这会如此糟糕,请考虑以下代码:

string[] strings = new []{"Hey there"};
object[] objects = strings;
objects[0] = new object();

噢,这会编译,但会在运行时失败。当我们试图将一个对象粘贴到一个字符串 [] 中时。好吧,我同意这很糟糕,但是 T[] 扩展了 Array 并且还实现了 IList (和 IList<T> ,我想知道它是否实现了 IList<BaseType> ...>。Array 和 IList 都让我们犯了同样可怕的错误。

string[] strings = new []{"Hey there"};
Array objects = strings;
objects.SetValue(new object(),new[]{0});

列表版本

string[] strings = new []{"Hey there"};
IList objects = strings;
objects[0] = new object();

T[] 类由 CLR 生成,并且必须包含对等同于 set_Item 的类型检查方法(数组实际上没有)。

是否担心设置为 T[] 必须在运行时进行类型检查(这违反了您在编译时期望的类型安全性)?为什么当有等效的方法通过上述提供的方法搬起石头砸自己的脚时,阵列显示此属性被认为是有害的?

最佳答案

In .NET reference type arrays are co-variant. This is considered a mistake.

一些人认为类型安全破坏数组协变是 .NET 设计中的一个错误。并不是所有人都这么认为的。我不认为这是一个错误;我认为这是一个不幸的选择。所有设计过程都涉及在不受欢迎的备选方案之间进行选择。在这种情况下,选择是添加一个不安全的隐式转换,对所有数组写入施加运行时成本,还是构建一个无法轻松实现 Java 类型系统的类型系统。这是一个艰难的选择,类型系统的设计者根据他们所掌握的信息做出了他们所能做出的最佳选择。

当然,这种解释只是在乞讨; Java 的设计者犯了一个错误,这难道不是简单的情况吗?可能是,也可能不是; Java 的设计者很可能在类型系统的设计中也面临着权衡。 Java 类型系统开发历史上的任何专家都想在这里插话这些权衡是什么,我很想知道。

凭借十年后见之明,如果 .NET 类型系统的设计者选择避开破坏安全的数组协变,我个人会更喜欢它。但这并不能使那个选择成为“错误”,它只会让它变得有些不幸。

Is the concern that setting to a T[] has to do the type check at runtime (which violates the type-safety you expect at compile time)?

是的。这意味着看起来应该始终成功运行的代码可能会在运行时失败。这意味着正确的代码会受到性能惩罚。

Why is it considered harmful for arrays to exhibit this property when there are equivalent means to shoot yourself in the foot through the provided means above?

这是一个奇怪的问题。问题本质上是“我已经有两把枪可以射中自己的脚,那么为什么用第三把枪射中自己的脚对我来说是有害的呢?”

两种违反类型安全的危险模式的存在不会降低第三种此类模式的危险性。

当您绝对肯定地知道您正在做的事情是安全的时候,即使编译器不知道,也会出现违反类型安全的语言和运行时功能。如果您对这些功能的了解程度不足以安全地使用它们,那么请不要使用它们。

关于c# - 为什么数组协方差被认为如此可怕?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4317459/

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