【问题标题】:Can I a implement DisposeBase abstract class?我可以实现 DisposeBase 抽象类吗?
【发布时间】:2010-09-21 15:00:59
【问题描述】:

在使用 DisposableBase base class 而不是在每个类上重新编码 Dispose 模式时是否存在问题或隐藏问题?

为什么不是每个人都使用这样的相关类?

编辑

  1. 我自然只指实现 IDisposable 的类

  2. 我知道它用尽了继承的选择权,但我愿意付出代价(至少在我可以的情况下,否则它不会伤害我)。

  3. 当我可以密封类时,我会这样做 - 但在某些情况下,我希望继承层次结构的基础是一次性的。

【问题讨论】:

    标签: c# .net inheritance design-patterns dispose


    【解决方案1】:

    您不需要在 每个 类上实现 Dispose() - 只需要那些需要确定性清理的东西。 Re 一个 Disposable 基类,我不完全确定它提供了很多 - IDisposable 不是一个复杂的接口。它可能有用的主要时间是,如果您正在处理非托管资源并想要一个终结器,但即便如此它也没有太多代码。

    就个人而言,我不会为这样的基类而烦恼。特别是,继承(在单一继承的世界中)很快就会受到限制。但更重要的是,重写一个方法与简单地提供一个公共 Dispose() 方法没有太大区别。

    再次重申:如果您正在处理非托管对象,则只需要一个终结器等。

    如果我有很多这些(非托管资源),我可能会看看是否可以让PostSharp 为我做这项工作。我不知道是否已经存在,但是可能可以创建一个处理(特别是)终结器等的方面。谁知道...

    【讨论】:

    • 查看原帖中的编辑。
    【解决方案2】:

    嗯,它使用了你的一个继承选项来描述你的类的一个方面——这并不理想,IMO。尝试使用组合来做一些事情会很有趣,您可以引用 DisposableHelper 并且 IDisposable 的实现只调用 helper.Dispose,其中包含其余的样板逻辑 - 并且可以通过 a 回调您的代码回调委托。唔。子类可以订阅受保护的 Disposing 事件来注册“我需要做某事”......这可能值得花点时间看看。

    就我个人而言,我发现自己实施 IDisposable 的频率不足以使其成为问题 - 当我这样做时,我通常无论如何都会密封我的课程,因此模式中的一半内容变得不成问题。

    【讨论】:

    • 我不认为作曲有效。辅助类可能在 IDisposable 类之前被垃圾回收。
    • 对 helper 的引用会阻止 GC 这样做
    • GC 只使用源自某个对象的引用,该对象实际上在某个范围内。帮助器需要是来自您的对象以外的其他东西的引用,以保证在您需要它时就在那里。将帮助器集合保存在中心位置可能会有所帮助,但这似乎很棘手。
    • Mendelt:帮助器和“真实”类将在任一实例被垃圾收集之前完成。
    【解决方案3】:

    正如 Marc Gravell 所说,只有在处理非托管对象时才需要终结器。根据Dispose, Finalization, and Resource Management 指南第 1.1.4 节中的原因,在基类中引入不必要的终结器是一个坏主意:

    存在与相关的实际成本 带有终结器的实例,都来自 性能和代码复杂度 立场。 ...最终确定增加了成本和持续时间 您的对象的生命周期为每个 可终结的对象必须放在 特殊终结器注册队列 分配时,本质上是创建 一个额外的指针大小的字段来引用 到你的对象。此外,对象在 这个队列在 GC 期间被遍历, 处理,并最终提升为 GC 使用的另一个队列 执行终结器。增加 直接可终结对象的数量 与更多对象相关 被提升到更高的世代,并且 花费的时间增加 GC 行走队列,移动指针 周围,​​并执行终结器。 此外,通过保持对象的状态 大约更长的时间,您倾向于使用内存 更长的时间,这 导致工作集增加。

    如果您使用 SafeHandle(和相关类),则从 DisposableBase 派生的任何类都不太可能需要最终确定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-02-25
      • 2018-12-16
      • 2020-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-07-10
      • 2014-02-17
      相关资源
      最近更新 更多