如何使用第三方库正确实现一次性模式

How to correctly implement disposable pattern with third-party libraries

假设我有以下 classes:

class Foo : IDisposable
{
  public void Dispose()
  {
    bar.Dispose();
  }

  private Bar bar = new Bar();
}

class Bar : IDisposable
{
  public void Dispose()
  {
    baz.Dispose();
  }

  private SomeThirdPartyLibraryClass baz = new SomeThirdPartyLibraryClass();
}

此代码在使用 using 语句时运行良好:

using (Foo foo = new Foo())
{
  // ...
}
// All resources should be disposed at this time

但是,如果由于某种原因此 class 的用户忘记使用 using 语句,资源将永远不会被释放。

根据 MSDN,我应该按以下方式实现一次性模式:

class Foo : IDisposable
{
  public void Dispose()
  {
    Dispose(true);
    GC.SuppressFinalize(this);
  }

  protected virtual void Dispose(bool disposing)
  {
    if (disposed)
      return; 

    if (disposing) {
      // Free any managed objects here.
      //
    }

    // Free any unmanaged objects here.
    //
    disposed = true;
  }

  ~Foo()
  {
    Dispose(false);
  }

  bool disposed = false;
  private Bar bar = new Bar();
}

Bar也一样)

但是我应该把 bar.Dispose();baz.Dispose(); 代码放在哪里呢?

应该在"managed cleanup"节下还是在"unmanaged cleanup"节下?

顾名思义,我不知道SomeThirdPartyLibraryClass的实现方式(反正可以随着时间的推移而改变)

那我该怎么办?

But where exactly should I place bar.Dispose(); and baz.Dispose(); code?

由于您的第三方库似乎是托管代码,因此它会放在 "managed cleanup" 部分。

您应该在 Dispose 的托管部分下调用 bar 和 baz 的 Dispose,因为对于您的 class 它们是托管对象。如果 bar 和 baz 有一些不受管理的东西,那么应该由它们各自的 classes 在它们的 Dispose/Finalize 实现中清理。