struct vs class实现接口

时间:2014-01-20 10:39:27

标签: c#

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

编译器抱怨:

  

无法隐式转换类型'System.Collections.Generic.List&lt; Tests.Program.FooStruct&gt;'到'System.Collections.Generic.IEnumerable&lt; Tests.Program.IFoo&gt;'。存在显式转换(您是否错过了演员?)

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

2 个答案:

答案 0 :(得分:2)

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

解决方法很简单:

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

答案 1 :(得分:1)

这已经在这里得到了解答 - Why covariance and contravariance do not support value type,但总结了它以便于查找。

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

这是由于CLR中强制执行的限制,Eric Lippert's Blog -

中对此进行了解释
  

接口和委托的协变和逆变转换   类型要求所有不同类型的参数都是引用类型

原因在MSDN中解释:

  

差异仅适用于参考类型;如果指定值类型   对于变量类型参数,该类型参数对于该变量是不变的   结果构造类型。