为什么这个协方差声明编译? [英] Why does this covariance declaration compile?

查看:273
本文介绍了为什么这个协方差声明编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑这个接口:

 接口测试和LT;出T>其中T:结构{} 



它编译没有错误或警告



讨论过这个问题,并在的协变和逆变常见问题解答




方差仅支持如果一个类型参数是引用类型。




所以,为什么上面的界面编译?这将在走出去的关键字是有意义的失败(或至少是警告)。我想这个问题归结为 - 是否有任何情况下使用退出在上面的例子中的关键字有什么差别



<? HR>

更新:这里有一个例子误导行为,可能漏网之鱼为不知道开发谁看上面的接口:

  typeof运算(IDummy).IsAssignableFrom(typeof运算(MYSTRUCT)); //应该返回true 
的typeof(ITEST< IDummy>)。IsAssignableFrom(typeof运算(ITEST<&MYSTRUCT GT;)); //返回false

如果编码器不知道方差不工作的值类型,他们会预计第二行返回真正 - 因为关键词 - 但它永远不会。这正是促使我问这个问题的错误...






另一个例子代码将编译,但产生意想不到的结果:

  ITEST<&MYSTRUCT GT;富= ...; 
VAR铸造=(ITEST< IDummy>)富;



我希望这个工作(不知道有关协变的限制引用类型),但它会导致一个System.InvalidCastException。


解决方案

有任何情况下在上面的例子中使用了关键字,使有什么区别?




不。你被允许在声明指定退出,你就永远不会能够与该类型的特定实例打交道时,实际利用它。



有关此计划的没有什么,因为它是一个可能的指示不正常工作,所以你基本上是要求一个的功能请求的编译器,禁止这种行为对显影剂的一部分有错误。该请求的响应(就像几乎任何其他功能要求),微软要么并不认为这是作为一个选项,如果他们这么做,确定它是不是值得花时间和精力去主动禁止这种行为。


Consider this interface:

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

It compiles without errors or warnings.

As discussed in this question, and mentioned in the Covariance and Contravariance FAQ:

Variance is supported only if a type parameter is a reference type.

So why does the above interface compile? It would make sense to fail (or at least warn) on the "out" keyword. I guess the question boils down to - is there any case where using out keyword in the above example makes any difference?


Update: Here's an example misleading behavior that may slip through for the unaware developer who looks at the Interface above:

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

If the coder isn't aware of variance not working for value types, they would expect the second line to return true - because of the out keyword - but it never will. This is exactly the bug that prompted me to ask this question...


Another example of code that would compile but produce unexpected results:

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

I would expect this to work (not knowing about the limitation of covariance to reference types) but it causes a System.InvalidCastException.

解决方案

is there any case where using out keyword in the above example makes any difference?

Nope. You're allowed to specify out in the declaration, you just won't ever be able to actually leverage it when dealing with a specific instance of that type.

Nothing about this program doesn't work properly, so you're essentially asking for a feature request of the compiler prohibiting this behavior as it is a likely indication of a mistake on the part of the developer. The response to that request is (just like virtually any other feature request) that Microsoft either didn't consider this as an option, or if they did, determined that it wasn't worth the time and effort to actively prohibit this behavior.

这篇关于为什么这个协方差声明编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆