Implement IDisposable

jbe2277 edited this page Dec 22, 2016 · 6 revisions

The primary use of the IDisposable interface is to release unmanaged resources. But it can also be useful for some managed-only cleanup (e.g. removing of event handlers). The usage of this interface is quite attractive because of the using C# keyword.

The MSDN Dispose Pattern provides a good introduction on how to implement the interface and how to use it. This article provides some extended guidelines and some minor adaptions of the MSDN description.

  • Avoid to implement the finalizer (C# destructor) because of performance reasons. The finalizer is only needed if the class is directly responsible for releasing unmanaged resources. Prefer the SafeHandle class for handling unmanaged resources.
  • Do Not throw exceptions in the dispose implementation. The using C# keyword hides the Dispose call and therefore an exception is not expected here. Furthermore, Dispose might be called from infrastructure code like IoC Containers which do not know how to handle exceptions which are thrown during disposing objects.
  • Consider that the Dispose method might be called more than once.
  • Consider to let the base class be responsible that the protected virtual dispose method is called just once.
  • Avoid to provide a Close method as alternative for Dispose. The .NET Framework uses this approach but it creates more confusion than simplifying the class usage.
  • Keep care when the method gets called by the finalizer (disposing is false). In this case do not access other objects. These objects might already be finalized because the garbage collector disposes them in an unpredictable order.
public class SampleClass : IDisposable
{
    // Use volatile because finalizers are called by a separate Thread
    private volatile bool isDisposed;  

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

    // Call this method from a subclass when you implement a finalizer (destructor).
    protected void Dispose(bool disposing)
    {
        if (isDisposed) { return; }
        isDisposed = true;

        OnDispose(disposing);
        if (disposing)
        {
            // Cleanup and call Dispose on objects for which this class is responsible 
            // here ...
        }
        // Free unmanaged resources here ...
    }

    // Override this method in a subclass to free, release or reset any resources.
    protected virtual void OnDispose(bool disposing) { }
}

Further readings

  1. MSDN Dispose Pattern
  2. MSDN IDisposable Interface
  3. CA1063: Implement IDisposable correctly