代码之家  ›  专栏  ›  技术社区  ›  mmiika

为什么要封一个班?

  •  109
  • mmiika  · 技术社区  · 17 年前

    我想听听在《经济学人》中大量密封课程背后的动机是什么。Net框架。密封类有什么好处?我无法理解为什么不允许继承是有用的,而且很可能不是唯一一个与这些类作斗争的。

    那么,为什么框架是这样设计的,打开所有东西难道不是一个牢不可破的改变吗?除了邪恶,一定还有别的原因吗?

    10 回复  |  直到 5 年前
        1
  •  109
  •   Mitch Wheat    17 年前

    类应该为继承而设计,或者禁止继承。为继承而进行设计是有代价的:

    • 它可以确定你的实现(你必须声明哪些方法将调用哪些其他方法,以防用户覆盖其中一个而不覆盖另一个)
    • 它揭示了你的实现,而不仅仅是效果
    • 这意味着你在设计时必须考虑更多的可能性
    • 像Equals这样的东西很难在继承树中设计
    • 它需要更多的文档
    • 子类化的不可变类型可能变为可变类型(ick)

    Effective Java的第17项对此进行了更详细的介绍——无论它是在Java的上下文中编写的,这个建议都适用于。NET也是。

    就我个人而言,我希望类在默认情况下是密封的。网。

        2
  •  42
  •   CVertex    17 年前
    • 有时类太珍贵了,不能被继承。
    • 运行时/反射可以在查找类型时对密封类进行继承假设。一个很好的例子是-建议密封属性以提高查找运行时的速度。类型。如果MyAttribute被密封,GetCustomAttributes(typeof(MyAttribute))将执行得更快。

    此主题的MSDN文章是 Limiting Extensibility by Sealing Classes .

        3
  •  15
  •   Ohad Schneider    9 年前

    看来 official Microsoft guidelines on sealing 自从大约9年前提出这个问题以来,他们已经从选择加入的理念(默认密封)转变为选择退出(默认不密封):

    X不要 没有充分理由这样做。

    密封一个类,因为你想不出可扩展性场景 这不是一个好理由。框架用户喜欢从类继承 各种不明显的原因,比如添加便利会员。看见 未密封类,以用户想要的非显而易见的原因为例 从类型继承。

    密封类的充分理由包括以下几点:

    • 该类是静态类。请参见静态类设计。
    • 该类将安全敏感机密存储在继承的受保护成员中。
    • 该类继承了许多虚拟成员以及密封它们的成本 个人因素将超过离开课堂的好处 未密封。
    • 类是一个需要非常快运行时间的属性 查找密封属性的性能级别略高 而不是未密封的。请参见属性。

    X不要 在密封类型上声明受保护或虚拟成员。

    根据定义,密封类型不能从继承。这意味着 无法调用密封类型上的受保护成员,并且虚拟 不能重写密封类型的方法。

    考虑 您覆盖的密封构件。引入虚拟成员可能导致的问题(在虚拟成员中讨论) 也适用于覆盖,尽管程度略低。 密封超控可以保护您免受这些问题的影响 继承层次结构中的点。

    事实上,如果你 search the ASP.Net Core codebase ,你只会发现大约30次 sealed class ,其中大部分是属性和测试类。

    我确实认为不变性守恒是支持密封的一个很好的论据。

        4
  •  4
  •   bruno conde    17 年前

    我在msdn文档中发现了这句话:“密封类主要用于防止派生。因为它们永远不能用作基类,一些运行时优化可以使调用密封类成员稍微快一些。”

    我不知道性能是否是密封类的唯一优势,就我个人而言,我还想知道其他原因。..

        5
  •  3
  •   Peter Parker    17 年前

    性能是一个重要因素,例如,java中的字符串类是final(<-sealed),其原因仅在于性能。 我认为另一个重要的一点是避免这里详细描述的脆弱基类问题: http://blogs.msdn.com/ericlippert/archive/2004/01/07/virtual-methods-and-brittle-base-classes.aspx

    如果你提供了一个框架,那么对于可维护性遗留项目来说,升级你的框架以避免脆弱的基类问题非常重要

        6
  •  1
  •   ihebiheb    13 年前

    密封用于防止“脆性基层问题”。我找到了一个 good article MSDN对此进行了解释。

        7
  •  0
  •   Edward Kmett    17 年前

    密封允许您实现一些微小的性能提升。在JIT和懒惰悲观主义的世界里,这不如在C++的世界里那么真实,但从那时起。NET并不像java编译器那样悲观,主要是因为不同的设计理念,它仍然有用。它告诉编译器,它可以直接调用任何虚拟方法,而不是通过vtable间接调用它们。

    当你想要一个“封闭的世界”来进行平等比较时,这一点也很重要。通常,一旦我定义了一个虚拟方法,我就非常需要定义一个真正实现这个想法的等式比较概念。另一方面,我可能能够使用virtual方法为类的特定子类定义它。密封该类可确保平等真正成立。

        8
  •  0
  •   Jeff Dunlop    11 年前

    密封类使管理可支配资源更容易。

        9
  •  0
  •   user3629577    8 年前

    要确定是否密封类、方法或属性,通常应考虑以下两点:

    通过自定义类的能力,派生类可能会获得潜在的好处。

    派生类可能会修改你的类,使它们不再正常工作或按预期工作。

        10
  •  0
  •   Dave Clark    8 年前

    另一个需要考虑的因素是,密封类不能在单元测试中被删除。来自 Microsoft's documentation :

    密封类或静态方法不能被存根,因为存根类型依赖于虚拟方法分派。对于这种情况,使用垫片类型,如使用垫片将您的应用程序与其他组件隔离开来进行单元测试中所述