为什么C#/ CLR不支持方法覆盖co / contra-variance?

时间:2009-05-07 21:29:58

标签: c# .net clr override covariance

有很多问题&关于解决C#限制的问题,不允许在重写时将方法返回(和参数)类型更改为兼容类型,但为什么在C#编译器或CLR中存在这种限制?正如我所看到的,如果允许共同/反向差异,没有任何东西可以破裂,那么背后的原因是什么呢?

可以要求扩展访问参数的类似问题 - 例如,使用公共方法覆盖受保护的内部方法(Java支持的内容,IIRC)

5 个答案:

答案 0 :(得分:3)

Eric Lippert已经比我更好地回答了这个问题。

查看他在Covariance and Contravariance in C#

上的系列节目

How does C# 4.0 Generic Covariance & Contra-variance Implmeneted?

编辑:Eric指出他并没有谈论返回类型的方差,但我决定在这个答案中保留链接,因为它是一个很酷的系列文章,如果查找这个主题,有人可能会发现它很有用。

这个功能已经requested,差不多5年前,微软已回复“谢谢你记录这个。我们听到了很多这样的请求。我们会在下一个版本中考虑它。”

现在我引用Jon Skeet,因为如果没有Jon Skeet的回答,它就不会是StackOverflow的正确答案。 Covariance and void return types

  

我强烈怀疑答案   在于CLR的实施   而不是任何深层语义   原因 - CLR可能需要   知道是否会发生   是一个返回值,为了做   堆栈适当的东西。   即便如此,它似乎有点可惜   优雅的条款。我不能说我   真的觉得需要这个   生活,这将是相当容易的   伪造(最多四个参数)   .NET 3.5只需编写转换器即可   从Func<X>Action<X>Func<X,Y>   到Action<X,Y>等等。它有点琐碎   虽然:)

答案 1 :(得分:2)

这个答案不是在谈论C#,但它帮助我更好地理解问题,也许它会帮助其他人:Why is there no parameter contra-variance for overriding?

答案 2 :(得分:0)

引入返回值协方差的接缝没有基本的缺点,因为Java和C ++已经使用过。然而,通过引入形式参数的逆方差,引起了真正的混淆。我认为C ++中的这个答案https://stackoverflow.com/a/3010614/1443505对C#也有效。

答案 3 :(得分:-1)

确实如此,你只需要等待VS2010 / .Net 4.0。

答案 4 :(得分:-1)

为了扩展Joel的答案 - CLR长期以来支持有限的方差,但是C#编译器在通用接口和委托上使用新的“in”和“out”修饰符之前不会使用它们。原因很复杂,我会试图解释,但它并不像看起来那么简单。

将“受保护的内部”方法改为“公共”方法;你可以用方法隐藏来做到这一点:

public new void Foo(...) { base.Foo(...); }

(只要参数等都是公开的) - 任何用途?