假设:
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&lt; MyApp.MyNS.IMyInterface&gt;'
而且必须写成:
IEnumerable<IMyInterface> myStructImps = new IMyInterface[]{
new MyStruct(0),
new MyStruct(1),
new MyStruct(2)
};
答案 0 :(得分:4)
问题是数组协方差。 This specification谈论它:
对于任何两个引用类型A和B,如果从A到B存在隐式引用转换(第6.1.4节)或显式引用转换(第6.2.3节),则数组中也存在相同的引用转换输入A [R]到数组类型B [R],其中R是任何给定的排名说明符(但两种数组类型都相同)
一个更简单的例子也是失败的
int[] c = new int[0];
object[] d = c;
,而
string[] c = new string[0];
object[] d = c;
工作正常。你基本上是想做同样的事情。您有一个值类型MyStruct
的数组,并且您试图隐式地将其强制转换为IMyInterface
,这不属于数组协方差规范。
答案 1 :(得分:1)
有效的那个做隐式装箱,然后投射到IMyInterface。问题是编译器不一定知道结构是IMyInterface。拳击然后投射让你将你的对象描述为IMyInterface。
我现在正在CLR Via C#中读到这个,所以如果你认为我误解了这个,请纠正我。
答案 2 :(得分:0)
结构不是一个类。实例化它们时有不同的规则。没有研究它,我的猜测是你的第一个例子中不能推断出类型,因为它不是一个类。当它是明确的,没有问题。