5

默认情况下,C# 中的方法是非虚拟的。This answer to another question解释了这样做的好处:

应该为继承设计类以便能够利用它。默认情况下拥有虚拟方法意味着类中的每个函数都可以插入并被另一个函数替换,这并不是一件好事。

甚至 Anders Hejlsberg似乎也给出了同样的理由

当我们在 API 中发布一个虚方法时,我们不仅承诺当你调用这个方法时,x 和 y 都会发生。我们还承诺,当您覆盖此方法时,我们将按照与其他方法相关的特定顺序调用它,并且状态将保持不变。[...] 您不希望用户在 API 中的任意点覆盖和挂钩,因为您不一定会做出这些承诺。

我同意这个推理:通常当我创建一个非私有方法时,我只想创建可以从类外的某个地方调用的代码。通常,不会考虑其他人如何覆盖此方法以及会产生何种影响。对于特殊情况,我可以用virtual信号来表示确实以覆盖有意义的方式创建了代码。

但是,默认情况下类仍然是未密封的。默认假设我花费了额外的精力来确保继承一个类是有意义的。

在这方面,有什么东西使类与方法不同吗?


编辑
我真的不知道如何改变搁置 - 基于意见的事情。我从不征求意见。也许我必须明确地说出来?

我不想发表意见。

一个正确的答案要么提供一个类与方法不同的例子,要么说明在这种情况下没有区别。

4

1 回答 1

9

我认为问题是“鉴于默认情况下方法应该是非虚拟的有充分的理由,为什么默认情况下类也不密封?”

还可以添加:C# 将默认可访问性设置为内部的,用于顶级类型,或私有的,用于类型的成员;也就是说,它选择了限制性更强、更安全的选项;如果开发人员想要一个限制更少、更危险的选项,他们可以选择加入。默认情况下密封也将选择更具限制性和更安全的选项作为默认选项。

另外:解封一个类从来都不是一个重大的改变,但是后来决定你希望你已经密封了一个类并且密封它是一个重大的改变。C# 通常更喜欢鼓励较少破坏性更改的设计选择,因此也出于这个原因,您会认为 C# 类默认情况下应该是密封的。

我们已经确定了为什么默认密封是一个好主意并且与 C# 中的其他设计选择一致的三个原因。那么为什么 C# 在这方面不一致,选择将非密封类设为默认值呢?

我不知道。我总是觉得它是 C# 中的一个小设计缺陷。我从来没有见过对这个选择有说服力的论据,我不知道它是否在早期的设计会议上进行过辩论;那是在我加入设计团队之前。

除非您遇到参加 2001 年设计会议的人并询问他们,否则您的问题可能不会得到满意的答案。

我习惯于密封我编写的每个类,除非我有理由将其设计为继承;我鼓励每个人都这样做。

于 2019-05-06T14:49:11.227 回答