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

时间:2016-06-29 12:14:00

标签: c# dispose unmanaged managed

假设我有以下类:

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

但是,如果由于某种原因,此类用户忘记使用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();代码?

是否应该在“托管清理”部分或“非托管清理”部分下?

顾名思义,我不知道SomeThirdPartyLibraryClass的实现(无论如何,它可以随着时间的推移而改变)。

那我该怎么办?

2 个答案:

答案 0 :(得分:1)

  

但我应该在哪里放置bar.Dispose();和baz.Dispose();码?

由于您的第三方图书馆似乎是托管代码,因此它会进入"托管清理"部分。

答案 1 :(得分:1)

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