gpt4 book ai didi

c# - C# 数组中的协方差被破坏?

转载 作者:IT王子 更新时间:2023-10-29 04:51:12 25 4
gpt4 key购买 nike

考虑以下带有协变类型参数 T 的泛型接口(interface) ITest,实现该接口(interface)的泛型类 Test,以及一个类 A 和子类 B:

interface ITest<out T> 
{    
T prop{ get;}
}
class Test<T> : ITest<T>
{    
public T prop{ get {
return default(T);    
}}
}
class A {    
}
class B: A {    
}

以下代码编译没有错误,但抛出运行时异常 System.ArrayTypeMismatchException:

ITest<A>[] a = new ITest<A>[1];
a[0] = new Test<B>(); //<-- throws runtime exception

但是这段代码工作得很好:

ITest<A> r = new Test<B>();

这已经在 Mono 2.10.2 (Unity3d 4.1) 上进行了测试。我认为这在某种程度上与数组中破坏的协方差有关(参见 http://blogs.msdn.com/b/ericlippert/archive/2007/10/17/covariance-and-contravariance-in-c-part-two-array-covariance.aspx )。

我不清楚为什么分配数组槽时发生的类型检查没有考虑协方差。

最佳答案

我已经在 Windows 7 上使用 .Net 4 编译并测试了 VS2010 中的给定代码,它工作正常,它没有给出运行时异常,因此您的问题似乎与 Mono 或 Unity 相关。

对于给定的代码,很难对问题所在做出假设。异常的确切类型和一些其他测试用例(即不使用接口(interface)的变体)将有助于缩小确切问题的范围,但这是 Mono|Unity 社区需要解决的问题。

至于与那篇文章有关联,则无关。

文章描述的是以下情况:

class A { }
class B: A { }
class C: A { }

A[] a = new B[1];
a[0] = new C(); //<-- throws ArrayTypeMismatchException

为了简化 Eric 在他的文章中所说的内容:

a 是一个变量,可以保存继承自的任何类型的数组 A.

a 被分配了一个 B 的数组,因此 a 是一个 B 的数组。

当用户尝试将新的 C 分配给 a 的元素时,有一个类型 不匹配,因为 a 实际上是 B 的数组,因此将 C 分配给 a 的元素等同于尝试将新 C 分配给包含 B 的变量,如下所示:

B b = new C();

将 a 分配为 C 的数组会出现类似的问题。

但是,由于 a 被定义为能够保存 A 的数组,因此用户可以分配一个 A 的数组,这将允许它接受 B 和 C 的值。

正因为如此,你问题中的代码看起来与这个问题有关,但实际上并不是因为a被分配为ITest的数组,意味着它应该能够存储ITest的类型并且抛出的运行时错误源于 Mono 或 Unity 运行时中的错误。

关于c# - C# 数组中的协方差被破坏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16542915/

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