IEnumerable<;IMyInterface>;隐含地来自类[],但不来自结构[].为什么?
本文关键字:结构 为什么 gt IMyInterface IEnumerable lt | 更新日期: 2023-09-27 17:53:29
给定:
public interface IMyInterface{
}
public class MyClass:IMyInterface{
public MyClass(){}
}
public struct MyStruct:IMyInterface{
private int _myField;
public MyStruct(int myField){_myField = myField;}
}
为什么我可以写:
IEnumerable<IMyInterface> myClassImps = new[] {
new MyClass(),
new MyClass(),
new MyClass()
};
但不是:
IEnumerable<IMyInterface> myStructImps = new[]{
new MyStruct(0),
new MyStruct(1),
new MyStruct(2)
};
这给了我以下警告:
错误29无法将类型"MyApp.MyNS.MyStruct[]"隐式转换为"System.Collections.Generic.IEnumerable<MyApp.MyNS.IMyInterface>'
必须改为:
IEnumerable<IMyInterface> myStructImps = new IMyInterface[]{
new MyStruct(0),
new MyStruct(1),
new MyStruct(2)
};
问题是数组协方差。这个规范谈论它:
对于任何两种引用类型A和B,如果存在从A到B的隐式引用转换(第6.1.4节(或显式引用转换
一个同样失败的简单例子是
int[] c = new int[0];
object[] d = c;
而
string[] c = new string[0];
object[] d = c;
工作良好。你基本上是在尝试做同样的事情。您有一个值类型为MyStruct
的数组,并试图将其隐式转换为IMyInterface
,这不在数组协方差规范中。
工作的执行隐式装箱,然后转换为IMyInterface。问题是编译器不一定知道该结构是IMyInterface。拳击然后施法让你把你的物体描述为IMyInterface。
事实上,我现在正在CLR Via C#中读到这篇文章,所以如果你认为我歪曲了这一点,请纠正我。
结构不是类。实例化它们时有不同的规则。如果不研究它,我的猜测是,在你的第一个例子中无法推断出类型,因为它不是一个类。如果它是明确的,就没有问题。