DZone Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world

Jason has posted 22 posts at DZone. View Full User Profile

The IDisposable Dispose Pattern

12.14.2009
| 4043 views |
  • submit to reddit
        This is a full sample of a mostly safe way to implement IDisposable in C# (or .NET in general). The Finalizer method should make up for clients that forget to call Dispose(). Dispose() should always be re-entrant and should only do the work it is required to do. Managed resources should never be disposed from inside the Finalizer. Methods and Properties should either reconstruct a disposed instance or throw an ObjectDisposedException. Finalizers and Dispose() should avoid throwing exceptions.

Read this for this pattern: http://www.bluebytesoftware.com/blog/2005/04/08/DGUpdateDisposeFinalizationAndResourceManagement.aspx
Read this for a better solution: http://www.codeproject.com/KB/dotnet/idisposable.aspx

public class DisposableGuy : IDisposable
{
  // Declare disposable resources as private and provide service methods for derived classes
  // Avoid letting derived classes or client objects get a direct reference to these resources
  private SomethingDisposable __SomeDisposableObject;
  private SomethingUnmanaged __SomeUnmanagedObject;

  // ... some methods that create instances of the disposable or unmanaged fields ...

  public void DoSomething()
  {
    AssertNotDisposed();
    // ... do more stuff ...
  }

  #region IDisposable Implementation

  protected bool __IsDisposed = false;

  ~DisposableGuy()
  {
    this.Dispose(false);
  }

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

  protected virtual void Dispose(bool disposing)
  {
    if (this.__IsDisposed) { return; }
    if (disposing)
    {
      this.DisposeManagedResources();
    }
    this.DisposeUnmanagedResources();
    this.__IsDisposed = true;
  }

  protected virtual void DisposeManagedResources()
  {
    if (null != this.__SomeDisposableObject)
    {
      this.__SomeDisposableObject.Dispose(); 
      this.__SomeDisposableObject = null; 
    }
  }

  protected virtual void DisposeUnmanagedResources()
  {
    if (null != this.__SomeUnmanagedObject)
    {
      Marshal.ReleaseComObject(this.__SomeUnmanagedObject); // or however is more appropriate
      this.__SomeUnmanagedObject = null;
    }
  }

  protected virtual void AssertNotDisposed()
  {
    if (this.__IsDisposed)
    {
      throw new ObjectDisposedException(GetType().FullName);
    }
  }

  #endregion
}