IEnumerable <imyinterface>隐式来自类[]但不来自Struct []。为什么?</IMyInterface的>

时间:2011-04-28 21:30:22

标签: c#

假设:

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)
};

3 个答案:

答案 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)

结构不是一个类。实例化它们时有不同的规则。没有研究它,我的猜测是你的第一个例子中不能推断出类型,因为它不是一个类。当它是明确的,没有问题。