为什么这个协方差声明会编译?
考虑这个界面:
interface Test where T : struct { }
它编译时没有错误或警告。
如本问题所述 ,并在协方差和反演法常见问题中提到:
仅当类型参数是引用类型时才支持差异。
那么为什么上面的接口编译? 对“out”关键字失败(或至少警告)是有意义的。 我想这个问题归结为 – 在上面的例子中使用out
关键字是否有任何区别?
更新 :这是一个误导性行为的示例,可能会让那些看不到上面界面的不知情的开发人员漏掉:
typeof(IDummy).IsAssignableFrom(typeof(MyStruct)); // should return true typeof(ITest).IsAssignableFrom(typeof(ITest)); // returns false
如果编码器不知道方差不适用于值类型,他们会期望第二行返回true
– 因为out
关键字 – 但它永远不会。 这正是导致我提出这个问题的错误……
另一个可编译但产生意外结果的代码示例 :
ITest foo = ...; var casted = (ITest)foo;
我希望这可以工作(不知道协方差对引用类型的限制),但它会导致System.InvalidCastException。
有没有在上面的例子中使用out关键字有什么区别?
不。 您可以在声明中指定out
在处理该类型的特定实例时,您将无法真正利用它。
关于这个程序的任何内容都无法正常工作,因此您实际上是在要求编译器禁止此行为的function请求 ,因为它可能表明开发人员存在错误。 对该请求的响应(就像几乎任何其他function请求一样),微软要么不认为这是一个选项,要么就是这样,确定不值得花时间和精力来主动禁止这种行为。