你什么时候打算上课?

Aan*_*Aan 81 .net c# oop c++-cli

在C#和C++/CLI中,关键字sealed(或NotInheritableVB)用于保护类免于任何继承机会(该类将是不可继承的).我知道面向对象编程的一个特性是继承,我觉得使用sealed反对这个特性,它会停止继承.是否有一个例子显示了sealed它的好处以及何时使用它的重要性?

Lou*_*ann 90

  1. 在实现安全功能的类上,使原始对象不能"模拟".

  2. 更一般地说,我最近与微软的一位人士进行了交流,他告诉我他们试图将继承权限制在真正有意义的地方,因为如果不加以处理,性能会变得昂贵.
    sealed关键字告诉CLR没有进一步的类来寻找方法,这会加快速度.

在当今市场上大多数性能增强工具中,您会找到一个复选框,它将密封所有未继承的类.
但要小心,因为如果你想通过MEF允许插件或程序集发现,你会遇到问题.

  • 密封很烂。它使测试变得更加困难 - 我想用 FakeItEasy 模拟几个 ASP.NET 类,但我不能,因为它们是密封的。 (6认同)
  • #1的原因听起来含糊不清,但假设我们大部分时间都不写"安全功能",这是否意味着#1几乎不适用?原因#2用于性能调整.我们谈论的性能差异有多大?它们是否足以证明改变非安全类的定义?即使答案是"是",理想情况下这也是一个编译器选项,即"为所有非密封类生成优化代码",而不是让我们的开发人员改变代码库. (4认同)
  • 我的意思是在重用库中密封类,特别是如果它们被第三方重用,然后重新集成(通过MEF)到代码库中.您的代码库可能不会继承给定的类,但第三方会继承. (3认同)
  • _如果不加以处理,性能会变得昂贵_这是否可以通过少于疯狂数量的疯狂测试来测量? (3认同)
  • 非常同意@RayLuo。我多次指出,人们在安全和性能不是真正问题的情况下密封了他们的班级。他们的“密封”只是阻止了我覆盖类的合理需要,使事情变得更加困难。就像 Warlike Chimpanzee 所说的那样,在测试中模拟类非常普遍。 (2认同)

Pet*_*erg 14

狒狒的优秀答案附录:

  1. 如果某个类不是为继承而设计的,则子类可能会破坏类不变量.这当然只适用于你正在创建一个公共API,但是根据我的经验,我会密封任何未明确设计为子类的类.

在相关说明中,仅适用于未密封的类:创建的任何方法virtual都是扩展点,或者至少看起来应该是扩展点.声明方法也virtual应该是一个有意识的决定.(在C#中,这是一个有意识的决定;在Java中,它不是.)


编辑:一些相关链接:

另请注意,Kotlin默认密封课程; 它的open关键字与Java finalsealedC#相反.(可以肯定的是,没有普遍认为这是一件好事.)

  • 密封类导致更多的头痛而不是好处.我不断发现开发人员密封课程的情况,导致我在应该简单的事情上遇到困难.停止密封课程,你不像你想象的那样诙谐.密封课程只有你必须,即使这样,重新考虑.只是我的意见,作为那个必须处理其他人的密封课程的人,我无法编辑/解封. (14认同)
  • @GantMan的评论实际上应该被认为是OP问题的答案之一,因为它基本上给出了答案为"何时?几乎没有.为什么?这就是为什么你不这样做的原因." 授予您应将您的评论重新发布为单独的答案,然后为其收集投票.:-) (6认同)
  • 这是对这个答案的引用吗:/sf/answers/544437211/?链接到它比(仅)命名该人更好 (2认同)