为什么C#中的方法不是自动虚拟的?

Alo*_*kin 10 c# virtual

可能重复:
为什么C#默认将方法实现为非虚方式?

定义哪些方法不可克服而不是可以克服的方法要少得多,因为(至少对我而言),当你设计一个类时,你不关心它的继承人是否会覆盖你的方法. ..

那么,为什么C#中的方法不会自动虚拟?这是什么常识?

jfs*_*jfs 25

Anders Hejlsberg在这次采访中回答了这个问题,我引述:

有几个原因.一个是表现.我们可以观察到,当人们用Java编写代码时,他们忘记了最终标记他们的方法.因此,这些方法是虚拟的.因为它们是虚拟的,所以它们表现不佳.与虚拟方法相关的只是性能开销.这是一个问题.

版本控制更重要的一个问题.虚拟方法有两种思想流派.思想学院说,"一切都应该是虚拟的,因为有一天我可能想要覆盖它." 实用主义思想源于构建在现实世界中运行的真实应用程序,他说:"我们必须真正关注我们虚拟化的东西."

当我们在一个平台上制作虚拟东西时,我们会对未来的演变做出很多承诺.对于非虚方法,我们保证当您调用此方法时,将发生x和y.当我们在API中发布虚拟方法时,我们不仅承诺当您调用此方法时,x和y将会发生.我们还承诺,当你重写这个方法时,我们将按照这个特定的顺序对它们进行调用,并且状态将在这个和那个不变量中.

每当你在API中说虚拟时,你就是在创建一个回调钩子.作为操作系统或API框架设计师,您必须非常小心.您不希望用户在API中的任意点上覆盖和挂钩,因为您不一定能够做出这些承诺.人们可能无法完全理解他们在做虚拟事物时所做的承诺.


Luk*_*keH 20

您应该关心在派生类中可以覆盖哪些成员.

决定制作虚拟的方法应该是一个深思熟虑的,经过深思熟虑的决定 - 不是自动发生的事情 - 与关于API公共表面的任何其他决策相同.

  • +1是,一旦你让虚拟的东西,你有很多更多的场景不由自主的想怎么你的类被别人使用的时候要考虑,这又增加了设计,实施和测试的复杂性. (3认同)
  • 而且我不再输入我的答案,因为它本质上是一个更罗嗦的版本.+1. (2认同)

Mar*_*ris 6

除了设计和清晰度之外,非虚拟方法在技术上也更好,原因如下:

  • 虚拟方法需要更长的时间来调用(因为运行时需要在虚拟查找表中导航以找到要调用的实际方法)
  • 无法内联虚方法(因为编译器在编译时不知道最终会调用哪个方法)

因此,除非您有特定的意图来覆盖该方法,否则最好是非虚拟的.


Nol*_*rin 5

惯例?没什么,我想.我知道Java自动使方法成为虚拟方法,而C#则不然,所以在某种程度上显然存在一些关于什么更好的分歧.就个人而言,我更喜欢C#默认 - 考虑重写方法比覆盖它们要少得多,因此显式定义虚方法似乎更简洁.