2014-01-20 95 views
11
private static void TestStructInterface() 
{ 
    IFoo foo1 = new FooClass(); // works 
    IFoo foo2 = new FooStruct(); // works 
    IEnumerable<IFoo> foos1 = new List<FooClass>(); // works 
    IEnumerable<IFoo> foos2 = new List<FooStruct>(); // compiler error 
} 

interface IFoo 
{ 
    string Thing { get; set; } 
} 

class FooClass : IFoo 
{ 
    public string Thing { get; set; } 
} 

struct FooStruct : IFoo 
{ 
    public string Thing { get; set; } 
} 

编译器会抱怨:结构VS类实现一个接口

无法隐式转换类型 'System.Collections.Generic.List <Tests.Program.FooStruct>' 到“System.Collections.Generic。 IEnumerable <Tests.Program.IFoo>'。存在明确的转换(您是否缺少演员?)

为什么?
为什么类和结构之间有区别? 任何解决方法?

+0

看到如此质疑http://stackoverflow.com/questions/13049/whats-the-difference-between-struct-and-class-in-net 而接受的答案:http://stackoverflow.com/a/13275/1155847 –

+0

也在这里:http://stackoverflow.com/questions/9688268/why-cannot-ienumerablestruct-be-cast-as-ienumerableobject –

+2

只是一个小事情关于术语:接口是“实现的”,而不是“继承的”。 –

回答

2

就像Bharathram Attiyannan回答的那样,方差根本不支持值类型。

解决方法很简单:

List<FooStruct> listOfFooStruct = new List<FooStruct>(); 
IEnumerable<IFoo> enumerableOfFoo = listOfFooStruct.Cast<IFoo>(); 
1

这已经在这里回答 - Why covariance and contravariance do not support value type,但总结它更容易查找。

您尝试实施的行为称为“差异”。

这是由于在CLR强迫的限制,其在Eric Lippert's Blog说明 -

协变和接口的反变转换,并委派 类型需要所有不同类型的参数是引用类型的

原因在MSDN中解释:

差异应用程序仅仅涉及参考类型;如果您为变体类型参数指定值类型 ,则该类型参数对于结果构造类型为 不变。

+0

感谢您的解释。你有解决方法的建议吗? –

+0

抱歉无法为您制定确切的解决方案..但是从我所了解的您需要明确地将Cast Struct输入到Class中。这个答案可能会帮助你 - http://stackoverflow.com/a/9688362/442444 – CarbineCoder