为什么 C# 默认将方法实现为非虚拟?

2022-08-31 09:59:07

与Java不同,为什么C#默认将方法视为非虚函数?它是否更有可能是性能问题,而不是其他可能的结果?

我想起了阅读Anders Hejlsberg的一段话,关于现有架构带来的几个优点。但是,副作用呢?默认情况下使用非虚拟方法真的是一个很好的权衡吗?


答案 1

类应设计为继承,以便能够利用它。默认情况下有方法意味着类中的每个函数都可以入并替换为另一个函数,这并不是一件好事。许多人甚至认为课程应该是默认的。virtualsealed

virtual方法也可能对性能有轻微的影响。然而,这不太可能是主要原因。


答案 2

我很惊讶,这里似乎有这样一个共识,即非虚拟默认是正确的做事方式。我将站在栅栏的另一边——我认为是务实的—— 一边。

在我看来,大多数理由都像是“如果我们给你权力,你可能会伤害自己”的旧论点。来自程序员?!

在我看来,那些没有足够的知识(或没有足够的时间)来设计他们的库以进行继承和/或可扩展性的程序员,而编码人员正是我可能不得不修复或调整的库的程序员 - 正是覆盖能力最有用的库。

我不得不编写丑陋的,绝望的解决代码(或放弃使用并推出我自己的替代解决方案)的次数,因为我无法覆盖很远,远远超过我被咬过的次数(例如在Java中),通过覆盖设计师可能没有考虑过的地方。

默认非虚拟使我的生活更加艰难。

更新:有人指出(非常正确)我实际上并没有回答这个问题。所以 - 并为相当晚而道歉....

我有点希望能够写一些简洁的东西,比如“C#默认将方法实现为非虚拟方法,因为做出了一个错误的决定,它比程序员更重视程序”。(我认为基于这个问题的其他一些答案,这可能是有道理的 - 比如性能(过早优化,有人吗?),或者保证类的行为。

然而,我意识到我只是在陈述我的观点,而不是Stack Overflow想要的明确答案。当然,我认为,在最高层面上,最终(但无益)的答案是:

默认情况下,它们是非虚拟的,因为语言设计人员已经做出了决定,这就是他们的选择。

现在我想他们做出这个决定的确切原因我们永远不会......哦,等等!对话的文字记录!

因此,这里关于覆盖API的危险以及显式设计继承的必要性的答案和评论似乎都走上了正确的轨道,但都缺少一个重要的时间方面:Anders的主要关注点是跨版本维护类或API的隐式契约。我认为他实际上更关心的是允许.Net / C#平台在代码下进行更改,而不是关注平台顶部的用户代码更改。(他的“务实”观点与我完全相反,因为他是从另一边看的。

(但是,难道他们不能默认选择虚拟,然后通过代码库进行“最终”吗?也许这并不完全相同。安德斯显然比我聪明,所以我会让它撒谎。


推荐