为什么 C# 类 默认情况下未密封,而默认情况下它们的方法是非虚拟的?
Why are C# classes unsealed by default, when their methods are non-virtual by default?
默认情况下,C# 中的方法是非虚拟的。 This answer to another question 解释这样做的好处:
Classes should be designed for inheritance to be able to take advantage of it. Having methods virtual by default means that every function in the class can be plugged out and replaced by another, which is not really a good thing.
甚至安德斯·海尔斯伯格 seems to give the same reason:
When we publish a virtual method in an API, we not only promise that when you call this method, x and y will happen. We also promise that when you override this method, we will call it in this particular sequence with regard to these other ones and the state will be in this and that invariant. [...] You don't want users overriding and hooking at any arbitrary point in an API, because you cannot necessarily make those promises.
我同意这个推理:通常当我创建一个非私有方法时,我只想创建可以从 class 之外的某个地方调用的代码。通常,不会考虑其他人如何覆盖此方法以及会产生什么影响。对于特殊情况,我可以使用 virtual
表示 确实 以覆盖有意义的方式创建了代码。
但是,class默认情况下仍未密封。 default 假设我花费了额外的努力来确保继承 class 是有意义的。
class在这方面与方法有什么不同吗?
编辑
我真的不知道要更改 搁置 - 基于意见的 事情。我从不征求意见。也许我必须明确地说出来?
我不要意见
正确答案要么提供一个 class 与方法不同的示例,要么说明在这种情况下没有区别。
我认为问题是 "given that there are good reasons why methods should be non-virtual by default, why are classes not also sealed by default?"
还可以添加:对于 top-level 类型,C# 使默认可访问性成为内部可访问性,或者对于类型成员,使默认可访问性成为私有;也就是说,它选择更严格和更安全的选项;如果开发人员希望有一个限制较少、更危险的选项,他们可以选择加入。默认密封也将选择更严格和更安全的选项作为默认选项。
另外:解封 class 从来都不是破坏性变更,但后来决定您希望将 class 密封并密封它是破坏性变更。 C# 通常更喜欢鼓励更少破坏性更改的设计选择,因此也出于这个原因,您会认为 C# classes 应该默认密封。
我们已经确定了默认密封是一个好主意并且与 C# 中的其他设计选择一致的三个原因。那么为什么 C# 在这方面不一致,选择将未密封 classes 作为默认值?
我不知道。它总是让我印象深刻,因为它是 C# 中的一个小设计缺陷。我从未见过对这个选择有说服力的论据,我不知道它是否在早期的设计会议上进行过辩论;那是在我加入设计团队之前。
除非你 运行 找到参加 2001 年那个设计会议的人并问他们,否则你的问题可能得不到满意的答案。
我习惯把我写的每一个class都密封起来,除非我有理由将其设计为继承;我鼓励大家也这样做。
默认情况下,C# 中的方法是非虚拟的。 This answer to another question 解释这样做的好处:
Classes should be designed for inheritance to be able to take advantage of it. Having methods virtual by default means that every function in the class can be plugged out and replaced by another, which is not really a good thing.
甚至安德斯·海尔斯伯格 seems to give the same reason:
When we publish a virtual method in an API, we not only promise that when you call this method, x and y will happen. We also promise that when you override this method, we will call it in this particular sequence with regard to these other ones and the state will be in this and that invariant. [...] You don't want users overriding and hooking at any arbitrary point in an API, because you cannot necessarily make those promises.
我同意这个推理:通常当我创建一个非私有方法时,我只想创建可以从 class 之外的某个地方调用的代码。通常,不会考虑其他人如何覆盖此方法以及会产生什么影响。对于特殊情况,我可以使用 virtual
表示 确实 以覆盖有意义的方式创建了代码。
但是,class默认情况下仍未密封。 default 假设我花费了额外的努力来确保继承 class 是有意义的。
class在这方面与方法有什么不同吗?
编辑
我真的不知道要更改 搁置 - 基于意见的 事情。我从不征求意见。也许我必须明确地说出来?
我不要意见
正确答案要么提供一个 class 与方法不同的示例,要么说明在这种情况下没有区别。
我认为问题是 "given that there are good reasons why methods should be non-virtual by default, why are classes not also sealed by default?"
还可以添加:对于 top-level 类型,C# 使默认可访问性成为内部可访问性,或者对于类型成员,使默认可访问性成为私有;也就是说,它选择更严格和更安全的选项;如果开发人员希望有一个限制较少、更危险的选项,他们可以选择加入。默认密封也将选择更严格和更安全的选项作为默认选项。
另外:解封 class 从来都不是破坏性变更,但后来决定您希望将 class 密封并密封它是破坏性变更。 C# 通常更喜欢鼓励更少破坏性更改的设计选择,因此也出于这个原因,您会认为 C# classes 应该默认密封。
我们已经确定了默认密封是一个好主意并且与 C# 中的其他设计选择一致的三个原因。那么为什么 C# 在这方面不一致,选择将未密封 classes 作为默认值?
我不知道。它总是让我印象深刻,因为它是 C# 中的一个小设计缺陷。我从未见过对这个选择有说服力的论据,我不知道它是否在早期的设计会议上进行过辩论;那是在我加入设计团队之前。
除非你 运行 找到参加 2001 年那个设计会议的人并问他们,否则你的问题可能得不到满意的答案。
我习惯把我写的每一个class都密封起来,除非我有理由将其设计为继承;我鼓励大家也这样做。