C#重载决策?

7

来自Anders Hejsberg采访的文章中提到,“我们在C#中进行重载决策的方式与其他任何语言都不同。” 有人可以提供一些关于C#和Java的例子吗?


1
我会从Eric Lippert的博客开始。有8篇带有overload resolution标签的文章。 - Roman
为什么需要一个例子?在Java中,您可以轻松地在子类中替换函数,在C#中,您将函数标记为虚拟的,然后可以重写它。 - James Black
@R0MANARMY:这是这个问题的正确答案。如果你把它作为答案发布,我会点赞的。 - Robert Harvey
4
@James:这是“覆盖”,而不是“重载”。 - Adam Robinson
@james,我在谈论重载而不是覆盖。 - northTiger
1
@Robert Harvey:我觉得这有点不负责任的回答。在SO上有很多人可以比“读X”更详细地回答这个问题。这些答案的内容对SO也更有价值。 - Roman
2个回答

19

Anders的意思是,最初的设计团队明确地设计了重载解析算法,使其具有在版本控制场景下表现良好的某些属性,尽管考虑没有版本控制的场景时,这些属性似乎是反向或令人困惑的。

在C#中,最常见的例子可能是以下规则:如果更派生类中的任何方法是适用的候选项,则它比较少派生类中的任何方法自动更好,即使较少派生的方法具有更好的签名匹配。据我所知,在其他具有重载解析的语言中并没有这个规则。这似乎是违反直觉的,如果有一个更好的签名匹配的方法,为什么不选择它呢?原因是因为更好的签名匹配的方法可能是在后续版本中添加的,从而引入“脆弱的基类”故障。

有关各种语言如何处理“脆弱的基类”故障的更多想法,请参见:

链接

有关重载解析的更多想法,请参见:

链接


2
你是否会在被提及的问题中收到页面通知,以确保无论何时都能回答? ;) - Roman
C++会自动隐藏所有与其同名的函数,如果在派生类中定义了一个函数。因此,除非您使用“using base::functionname”声明(即“取消隐藏”该名称),否则效果是类似的。但这并不完全相同,因为在C ++中,即使在更派生的类中没有可应用的重载,这些隐藏的名称也将不被考虑。它的作用是相同的-基类中的新函数不会被意外调用。 - Paul Groke

1

C#从内部角度处理重载的方式是不同的。

Anders的完整引用:

我一直把自己描述为一个实用主义者。有趣的是,版本控制最终成为我们语言设计的支柱之一。它出现在你如何覆盖C#中的虚拟方法上。此外,我们在C#中执行重载决策的方式与我所知道的任何其他语言都不同,原因是版本控制。每当我们考虑设计特定功能时,我们总是会与版本控制进行交叉检查。我们会问:“版本控制如何改变这个?从版本控制的角度来看,这个函数如何?”结果发现,大多数语言设计以前很少考虑到这一点。


嗯...这解释了他的另一个问题 - Roman

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接