IEnumerable<IMyInterface> Implicitly From Class[] But Not From Struct[]. Why?
Given:
public interface IMyInterface{
}
public class MyClass:IMyInterface{
public MyClass(){}
}
public struct MyStruct:IMyInterface{
private int _myField;
public MyStruct(int myField){_myField = myField;}
}
Why can I write:
IEnumerable<IMyInterface> myClassImps = new[] {
new MyClass(),
new MyClass(),
new MyClass()
};
But not:
IEnumerable<IMyInterface> myStructImps = new[]{
new MyStruct(0),
new MyStruct(1),
new MyStruct(2)
};
Which gives me the following开发者_JAVA技巧 warning:
Error 29 Cannot implicitly convert type 'MyApp.MyNS.MyStruct[]' to 'System.Collections.Generic.IEnumerable<MyApp.MyNS.IMyInterface>'
And must instead be written:
IEnumerable<IMyInterface> myStructImps = new IMyInterface[]{
new MyStruct(0),
new MyStruct(1),
new MyStruct(2)
};
The issue is array covariance. This specification talk about it:
For any two reference-types A and B, if an implicit reference conversion (Section 6.1.4) or explicit reference conversion (Section 6.2.3) exists from A to B, then the same reference conversion also exists from the array type A[R] to the array type B[R], where R is any given rank-specifier (but the same for both array types)
A simpler example of this that also fails is
int[] c = new int[0];
object[] d = c;
while
string[] c = new string[0];
object[] d = c;
works fine. You are basically trying to do the same thing. You have an array of value types MyStruct
and you are trying to implicitly cast it to IMyInterface
, which is not covered by the array covariance specification.
The one that works does implicit boxing, then casting to an IMyInterface. The problem is that the compiler doesn't necessarily know that the struct is a IMyInterface. Boxing then casting gets you that describe your object as an IMyInterface.
I'm actually reading about this in CLR Via C# right now, so if you think I've misrepresented this, please correct me.
A struct is not a class. There are different rules when instantiating them. Without researching it, my guess is that the type can not be inferred in your first example because it is not a class. When it is explicit, there is no problem.
精彩评论