为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

慕姐4208626 2019-12-20 09:55:50
与Java不同,为什么C#默认将方法视为非虚函数?它是否更可能是性能问题而不是其他可能的结果?我想起了安德斯·海斯伯格(Anders Hejlsberg)读的一段有关现有体系结构所带来的优势的文章。但是,副作用呢?默认情况下使用非虚拟方法真的不错吗?
查看完整描述

3 回答

?
缥缈止盈

TA贡献2041条经验 获得超4个赞

我很惊讶这里似乎达成了这样的共识,即默认非虚拟化是正确的处理方式。我要讲的是栅栏的另一面-我认为是实用的。


大多数论据都像古老的“如果我们给你力量,你可能会伤害自己”这样的论点读给我听。来自程序员吗?


在我看来,像编码员一样,他不了解(或没有足够的时间)来设计自己的库以进行继承和/或可扩展性,是恰好产生了我可能需要修复或调整的库的编码员。覆盖功能最有用的库。


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


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


更新: [正确地指出]我实际上没有回答问题。所以-很抱歉迟到了....


我有点希望能够写出一些像“ C#在默认情况下将方法实现为非虚拟的方法,因为做出了一个错误的决定,使程序对程序的重视程度高于程序员”。(我认为,根据该问题的其他一些答案(例如性能(过早的优化,有人吗?)或保证类的行为),这在某种程度上是合理的。)


但是,我意识到我只是在陈述自己的观点,而不是Stack Overflow想要的明确答案。当然,我认为,在最高层次上,确定的(但无济于事的)答案是:


默认情况下,它们是非虚拟的,因为语言设计者需要做出决定,而这正是他们选择的。


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


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


(但是他们不能只是默认情况下选择了虚函数,然后在代码库中添加了“最终”字吗?也许那是不完全一样的。而且安德斯显然比我聪明,所以我要撒谎。)


查看完整回答
反对 回复 2019-12-20
?
小唯快跑啊

TA贡献1863条经验 获得超2个赞

总结一下别人说的话,有以下几个原因:

1-在C#中,语法和语义上有很多东西直接来自C ++。C ++默认情况下不是虚拟的方法会影响C#。

2-默认情况下,将每个方法虚拟化是性能问题,因为每个方法调用都必须使用对象的虚拟表。而且,这极大地限制了即时编译器内联方法和执行其他类型的优化的能力。

3-最重要的是,如果默认情况下方法不是虚拟的,则可以保证类的行为。当它们默认为虚拟时(例如在Java中),您甚至无法保证简单的getter方法会按预期进行,因为它可能会被覆盖以在派生类中做任何事情(当然,您可以并且应该使方法和/或最终课程)。

正如Zifre所提到的,您可能会想知道为什么C#语言没有更进一步,并且默认情况下将类密封。这是关于实现继承问题的整个辩论的一部分,这是一个非常有趣的话题。


查看完整回答
反对 回复 2019-12-20
  • 3 回答
  • 0 关注
  • 574 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信