为什么这个协方差声明会编译?

时间:2013-05-24 16:07:51

标签: c# covariance compiler-bug

考虑这个界面:

interface Test<out T> where T : struct { }

编译时没有错误或警告。

正如this question中所述,并在the Covariance and Contravariance FAQ中提及:

  

仅当类型参数是引用类型时才支持方差。

那么为什么上面的接口编译?对“out”关键字失败(或至少警告)是有意义的。我想这个问题归结为 - 在上面的例子中使用out关键字是否有任何区别?


更新:这是一个误导性行为示例,可能会让那些看不到上面界面的不知情的开发人员漏掉:

typeof(IDummy).IsAssignableFrom(typeof(MyStruct)); // should return true
typeof(ITest<IDummy>).IsAssignableFrom(typeof(ITest<MyStruct>)); // returns false

如果编码器不知道方差不适用于值类型,他们会期望第二行返回true - 因为out关键字 - 但它永远不会。这正是导致我提出这个问题的错误......


另一个可编译但会产生意外结果的代码示例

ITest<MyStruct> foo = ...;
var casted = (ITest<IDummy>)foo;

我希望这可以工作(不知道协方差对引用类型的限制),但它会导致System.InvalidCastException。

1 个答案:

答案 0 :(得分:2)

  

在上面的例子中使用out关键字是否有任何区别?

不。您可以在声明中指定out,在处理该类型的特定实例时,您将无法真正利用它。

这个程序的任何内容都无法正常工作,因此您实际上是要求编译器的功能请求禁止此行为,因为它可能表明该程序存在错误。开发商。对该请求的响应(就像几乎任何其他功能请求一样),微软要么不认为这是一个选项,要么就是这样,确定不值得花时间和精力来主动禁止这种行为。 / p>