c# - 为什么 C# 类在默认情况下是非虚拟的,而默认情况下它们的方法是非虚拟的?

标签 c# class-visibility

<分区>

默认情况下,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.

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

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

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


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

我不想要意见。

正确答案要么提供类与方法不同的示例,要么声明在此上下文中没有区别。

最佳答案

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

还可以添加:C# 将默认可访问性设置为内部(对于顶级类型)或私有(private)(对于类型成员);也就是说,它选择更严格和更安全的选项;如果开发人员希望有一个限制较少、更危险的选项,他们可以选择加入。默认密封也将选择更严格和更安全的选项作为默认选项。

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

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

我不知道。它总是让我印象深刻,因为它是 C# 中的一个小设计缺陷。我从未见过对这个选择有说服力的论据,我不知道它是否在早期的设计 session 上进行过辩论;那是在我加入设计团队之前。

除非你遇到参加 2001 年那个设计 session 的人并问他们,否则你的问题可能得不到满意的答案。

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

关于c# - 为什么 C# 类在默认情况下是非虚拟的,而默认情况下它们的方法是非虚拟的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56007420/

相关文章:

c# - sql异常,缺少参数化查询

c# - Controller Action 中的 UrlHelper 未构建正确的 URL

c# - 如何将不在磁盘上的程序集动态加载到 ASP .Net Web 应用程序中?

c++ - 子类会影响虚拟方法的可见性吗?

java - 包保护类中的公共(public)方法是否有任何理由?

C++:私有(private)嵌套类类型的公共(public)成员

c# - 如何在调试应用程序期间定义事务超时

C# 无法访问 Newtonsoft.Json.Linq.JValue 上的子值

java - 如何实现可见性受限的Java图数据结构和类?

java - “public”函数公开其 'public/*package*/' 参数类型 SolarEdgeException