【发布时间】:2010-10-24 15:23:11
【问题描述】:
有很多关于破解 C# 的限制的问题和答案,不允许将方法返回(和参数)类型更改为覆盖时的兼容类型,但为什么存在此限制,在 C# 编译器中还是在 CLR 中?正如我所见,如果允许协方差,就没有什么可以破坏的,那么它背后的原因是什么?
类似的问题可能会被问到扩大访问参数 - 例如用公共方法(Java支持的东西,IIRC)覆盖受保护的内部方法
【问题讨论】:
标签: c# .net clr overriding covariance
有很多关于破解 C# 的限制的问题和答案,不允许将方法返回(和参数)类型更改为覆盖时的兼容类型,但为什么存在此限制,在 C# 编译器中还是在 CLR 中?正如我所见,如果允许协方差,就没有什么可以破坏的,那么它背后的原因是什么?
类似的问题可能会被问到扩大访问参数 - 例如用公共方法(Java支持的东西,IIRC)覆盖受保护的内部方法
【问题讨论】:
标签: c# .net clr overriding covariance
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>等。它有点琐碎 虽然:)
【讨论】:
这个答案不是在谈论 C#,但它帮助我更好地理解了这些问题,也许它会帮助其他人:Why is there no parameter contra-variance for overriding?
【讨论】:
引入返回值协方差的接缝没有 Java 和 C++ 使用过的本质缺陷。但是,引入形式参数的逆变会引起真正的混乱。我认为 C++ 中的这个答案https://stackoverflow.com/a/3010614/1443505 也适用于 C#。
【讨论】:
确实如此,你只需要等待VS2010/.Net 4.0。
【讨论】:
为了扩展 Joel 的答案 - CLR 长期以来一直支持有限的变化,但 C# 编译器直到 4.0 才使用它们,并在通用接口和委托上使用新的“in”和“out”修饰符。原因很复杂,我会陷入混乱试图解释,但它并不像看起来那么简单。
将“受保护的内部”方法重新制作为“公共”方法;你可以通过隐藏方法来做到这一点:
public new void Foo(...) { base.Foo(...); }
(只要参数等都是公开的)- 有什么用吗?
【讨论】: