Ani*_*oni 1 c# oop contravariance
C#支持返回类型协变,但为什么不支持参数类型逆变。
想象一下这个例子:
abstract class Animal
{
public abstract void PlayWith(Toy toy);
}
class PlayfulMonkey : Animal
{
public override void PlayWith(Object toy) // PlayfulMonkey can play with anything
{
// Monkey playing with its object...
}
}
Run Code Online (Sandbox Code Playgroud)
当您尝试执行此操作时,C# 编译器会向您抛出错误。但我觉得允许这样做是很有意义的。
Eri*_*ert 19
“为什么不”问题的前提是该功能显然非常好,设计人员应该为您提供一个不花费时间、金钱和精力来实现该功能的理由。但这不是语言设计的工作原理。可能的功能数量巨大,请求该功能的人有责任不仅解释为什么它是一个好功能,而且解释为什么它比设计团队可能花时间研究的所有其他功能更好。
人们要求返回类型协方差实际上已经有二十年了,而且花了这么长时间才达到优先级列表的首位。为什么需要这么长时间才能获得返回类型协方差?因为 (1) 设计团队认为它的优先级较低,(2) 实现并非微不足道,因为 CLR 中的底层类型系统不支持虚拟方差,(3) 总是有更高优先级的工作项,我们认为这些工作项的优先级更高。物超所值。
参数类型逆变有意义吗?当然。除了你之外还有人要求吗?据我所知。“这是有道理的”远不是一个足够好的理由;数以百万计的功能“有意义”,但只有少数功能在任何版本中得到实现。
设计团队的工作不是向您解释为什么您喜欢的功能不在他们的优先列表中。如果你想要这个功能,你有责任去 roslyn github,找到现有的设计请求(如果有的话),打开一个新的(如果没有),并提出一个令人信服的论点,证明这是最重要的事情。设计团队应该花时间在. 在您的论点中,我建议您重点关注通过添加此功能可以为专业业务线开发人员解决的所有现实问题。我不知道,但也许你知道。
附录:我忘了提及,如果您确实对此功能提出争论,您应该预料到以下阻力。假设 Alpha 团队这样写:
class Alpha
{
public virtual void M(Giraffe g) { alpha implementation }
}
Run Code Online (Sandbox Code Playgroud)
然后 Bravo 团队说让我们扩展 Alpha:
class Bravo : Alpha
{
public override void M(Giraffe g) { bravo implementation }
}
Run Code Online (Sandbox Code Playgroud)
然后 Charlie 团队说让我们扩展 Bravo:
class Charlie : Bravo
{
public override void M(Giraffe g) { charlie implementation }
}
Run Code Online (Sandbox Code Playgroud)
然后 Bravo 团队说哦,等等,我们可以做得更好,我们的方法实际上接受任何哺乳动物,让我们使用新的参数类型逆变特征,然后它们更改为:
class Bravo : Alpha
{
public override void M(Mammal g) { bravo implementation }
}
Run Code Online (Sandbox Code Playgroud)
Charlie 团队在使用最新版本的 Bravo 时是否会遇到构建中断?为什么或者为什么不?如果 Charlie 实施只处理长颈鹿,那么他们现在是否需要处理任何哺乳动物,因为 Bravo 可以?
C# 设计者尽量避免添加新版本的“脆弱基类”故障模式;如果有令人信服的好处,他们就会这样做,所以再次,在你的论点中找出令人信服的好处,说明为什么采取新形式的版本控制失败是可以接受的。