【问题标题】:Why are C# classes unsealed by default, when their methods are non-virtual by default? [closed]当 C# 类的方法默认为非虚拟时,为什么 C# 类默认不密封? [关闭]
【发布时间】:2019-09-24 05:17:30
【问题描述】:

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

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

甚至是安德斯·海尔斯伯格seems to give the same reason

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

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

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

在这方面有什么使类与方法不同的地方吗?


编辑
我真的不知道对 on hold - 基于意见 的事情要改变什么。我从不征求意见。也许我必须明确地说出来?

我不想要意见。

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

【问题讨论】:

  • “默认虚拟”我认为您的意思是“默认未密封”,对吗? *Virtual" 不是我们通常用于类的形容词。
  • 为什么标题说方法默认是虚拟的,而问题的第一句话说它们默认是非虚拟的?
  • @Amy 是的,现在我完全对术语感到困惑:D 谢谢,我调整了。
  • “基于意见”的逻辑是,只有少数人明确知道答案的为什么(或为什么不)问题往往会吸引未来源意见而非事实的答案。我不同意这种评估,并且更愿意结束诸如“不清楚你在问什么”之类的问题,因为“为什么”和“为什么不”的问题通常非常模糊。这是写得很好的“为什么不呢?”的一个很好的例子。题;很清楚你为什么要问,你正在寻找什么样的解释,你已经完成了你的研究,所以谢谢你。

标签: c# class-visibility


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

  • 如果封闭一个类是一个破坏性的改变,那么现在改变 default 行为将是毁灭性的。
  • 我不得不承认我有点生气。在我花了半个多小时写完这个问题后,你写了一个更好版本的我的问题
  • @C.Evenhuis:没错;现在不能改变这种行为,否则会造成比它所防止的伤害更大的伤害。
  • @RaphaelSchmitz 如何阅读 Eric 的文章 Why Are So Many Of The Framework Classes Sealed?,因为它很好地解释了密封类。
  • @RaphaelSchmitz:六分钟,加上每天八小时学习 C# 设计的七年。我无意惹你生气。
猜你喜欢
  • 2010-11-01
  • 1970-01-01
  • 2022-09-25
  • 1970-01-01
  • 2011-12-15
  • 2022-07-07
  • 2011-09-30
  • 1970-01-01
  • 2017-01-24
相关资源
最近更新 更多