c# - 这将是 IDisposable 的有效基类吗

标签 c# architecture finalizer disposable

IDisposable 模式的实现成本很高。在开始实际处理资源之前,我已经数了 17 行代码。

Eric Lippert 最近写了一篇 blog post提出一个有趣的观点:任何时候终结器运行时,它都是一个错误。我认为这是完全有道理的。如果始终遵循 IDisposable 模式,则应始终抑制 Finalizer。它永远没有机会运行。如果我们承认终结器运行是一个错误,那么制定一个指南来强制开发人员从以下抽象类派生并禁止直接实现 IDisposable 接口(interface)是否有意义。

public abstract class AbstractDisaposableBase: IDisposable
{
    ~AbstractDisaposableBase()
    {
        ReportObjectLeak();
        Dispose(false); 
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected abstract void Dispose(bool disposing);

    [Conditional("DEBUG")]
    private void ReportObjectLeak()
    {
        //Debug.Assert(false, "leaked instance");
        //throw new Exception("leaked instance");
    }
}

好处很明显:

  1. 实现处置变得简单且无错误,如下所示:

class MyClass1 : DisablableBase { protected override void Dispose(bool disposing) { //dispose both managed and unmamaged resources as though disposing==true } }
  1. 已报告未处理对象

  2. 一律遵循一次性模式

但是,这样的指导方针有什么问题吗?

一个可能的问题是所有一次性对象都将定义一个终结器。但由于终结器始终被抑制,因此不应有任何性能损失。

你有什么想法?

最佳答案

does it make sense to have a guideline to force developers to derive from the following abstract class

不,完全是因为 C# 没有多重继承。接口(interface)描述行为,继承决定“is-a”。如果强制执行此规则,您将彻底限制类的面向对象设计。

例如,您不能为非一次性的业务对象引入基类,派生类应该是。

关于c# - 这将是 IDisposable 的有效基类吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32373539/

相关文章:

Java 终结器 : An acceptable use-case?

c# - IDisposable with member from missing external assembly 在终结器中失败

C# XML 在 xml 标签后插入注释到 XML

c# - 如何通过 .NET 访问 ARP 协议(protocol)信息?

oop - 在构建词法分析器/扫描器时如何使用面向对象的设计范例?

ruby-on-rails - Rails 3 和 iOS 架构回顾

c# - 通过 Automapper 将枚举属性映射到数组

C#:带有用于单元测试的静态类的 DI

java - 跟踪多个系统上的用户

c# - 为什么java和c#有终结器?