问题 为什么C#4.0的协方差/逆变仅限于参数化接口和委托类型?


这是CLR的限制还是现有代码存在兼容性问题?

这与C#4.0中委托合并的混乱变化有关吗?

编辑: 在CLR上运行没有限制的共同/逆变语言是否可能?


12682
2017-08-04 13:20


起源

C#委托方差如何搞砸了? - thecoop
@thecoop: stackoverflow.com/questions/2306814 - soc
请注意,Eric的评论说代表 结合 在方差方面都搞砸了 - 一般来说不是一般的代表。 - Jon Skeet
可能重复 为什么C#4.0中的类没有通用方差? - Ian Ringrose
可能重复 为什么C#(4.0)不允许泛型类型中的共同和逆变? - nawfal


答案:


简单回答:这是一个CLR限制。

(我没有 看到 对于这个任何地方都有一个好的,具体的解释......我不记得在Eric的博客系列中看过一个关于它的内容,尽管我可能在某个地方错过了它。)

有一点我  说是代表和接口已经形成了真实类型的“间接层”;如果愿意,可以查看方法或类。从一个视图转换到另一个视图是相当合理的。对于我来说,实际的阶级感觉就像是一个更具体的表现 - 从一个具体的表现形式转移到另一个具体表现形式感觉不太合这是一个非常敏感的解释,而不是真正的技术限制。


5
2017-08-04 13:26



听起来很糟糕。那么基本上微软会重复Sun对Generics所犯的错误吗?或者是否计划在将来更新到CLR时解除这些限制? - soc
实施不是“错误” - 这是他们想到的明确的设计决策,他们有理由以他们的方式实施它。 - thecoop
@soc:是的 没有 就像Sun在仿制药方面的错误一样。是否有人猜测他们是否可能在将来的版本中允许它。 - Jon Skeet
@thecoop:我不想说他们没有比较所有技术上可行的解决方案,而是选择了他们认为最好的解决方案。但这是 究竟 当人们问为什么他们不做正确的仿制药时,Sun给我们的理由。我已经可以闻到,这个决定将在几年后成为PITA。 - soc
@Jon Skeet:很有意思。什么可以让Oracle考虑添加JVM支持,看到他们正在努力甚至让闭包/ SAM /“后卫”方法/扩展方法/尾部调用正确? - soc


您将要阅读Eric Lippert关于它为何如此工作的帖子。缺点是它们允许尽可能多的差异,而不允许开发人员在编程中犯下可能导致难以追踪错误的错误。 4.0中的差异量大大超过了3.0规则,从我的理解中,它是对开发人员有利的东西和允许安全的东西之间的平衡,而不会因为无意的错误而引起太多的麻烦。

http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/default.aspx


8
2017-08-04 13:25



虽然我可以理解对可用性的担忧,但是Java在很长一段时间内都有这个问题。我可以想象这种限制会产生更复杂,更有问题的变通方法,而不是简化事物。 - soc
Java和.NET泛型以完全不同的方式实现 - Java是编译时,.NET是运行时。并且添加功能(类方差)总是会产生更多的工作和更多要考虑的问题。 - thecoop
@thecoop:您在回答时谈到了开发人员的观点,而不是实施方面的技术难点。因此,如何在JVM / CLR上实现方差的实现细节并不是开发人员真正关心的问题。 - soc


这是CLR的限制。看到 为什么C#(4.0)不允许泛型类型中的共同和逆变? 进一步评论。


2
2017-08-04 16:17