Disposable Base Class

I have covered the IDisposable interface in my previous posts IDisposable and using in C# and Implementing IDisposable. To make the implementation of IDisposable easier, I have written an abstract base class that handles the details of the IDisposable pattern. The objectives of the class is to:

  • Provide a simple, reusable implementation of the disposable pattern.
  • Pass all code analysis rules.

The Disposable Class

/// <summary>
/// A general implementation of the disposable pattern. 
/// See http://coding.abel.nu/2012/01/disposable
/// </summary>
public abstract class Disposable : IDisposable
{
    /// <summary>
    /// Implementation of IDisposable.Dispose method.
    /// </summary>
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
 
    /// <summary>
    /// Is this instance disposed?
    /// </summary>
    protected bool Disposed { get; private set; }
 
    /// <summary>
    /// Dispose worker method. See http://coding.abel.nu/2012/01/disposable
    /// </summary>
    /// <param name="disposing">Are we disposing? 
    /// Otherwise we're finalizing.</param>
    protected virtual void Dispose(bool disposing)
    {
        Disposed = true;
    }
 
    /// <summary>
    /// Finalizer.
    /// </summary>
    ~Disposable()
    {
        Dispose(false);
    }
}

Rewriting the LogWriter

In the Implementing IDisposable post I used a LogWriter class as a sample. With the Disposable base class it can be rewritten.

public class LogWriterFromDisposable : Disposable
{
    private StreamWriter m_Stream;
 
    public LogWriterFromDisposable(string logFile)
    {
        m_Stream = new StreamWriter(logFile, true);
        m_Stream.WriteLine("Starting logging at {0}", DateTime.Now);
    }
 
    public void WriteLine(string message)
    {
        m_Stream.WriteLine(message);
    }
 
    protected override void Dispose(bool disposing)
    {
        if (!Disposed && disposing)
        {
            m_Stream.Dispose();
        }
 
        base.Dispose(disposing);
    }
}

Instead of having an entire section for IDisposable there is now just one method.

Limitations of a Base Class

As C# only supports single inheritance it is only possible to use the Disposable base class if there is no need to inherit another class, but that is not as hard a limitation at all. Any subclass should always be possible to use anywhere a base class is expected. If the subclass introduced a requirement of disposing, that principle would not hold. It is always preferable to have the base class in a class hierarchy implement IDisposable if any class requires it. Or put the other way: Never implement IDisposable in a sub class if the base class doesn’t.

This post is part of the IDisposable series.<< Implementing IDisposableUsing and Disposing of WCF Clients >>

3 comments

  1. You may also add the support for multi dispose calls by adding a disposed variable checked in Dispose() call.

  2. This is cleaner code, no?

    public abstract class Disposable : IDisposable
    {
      protected bool Disposed { get; private set; }
     
      /// 
      /// Frees resources
      /// 
      public void Dispose()
      {
        if (!Disposed)
        {
          Disposed = true;
          Dispose(Disposed);
        }
        GC.SuppressFinalize(this);
      }
     
      protected abstract void Dispose(bool disposing);
    }
    1. Yes, it’s somewhat cleaner. But it also requires the sub class to implement the Dispose(bool) method. And there are cases where that’s not needed. Consider if you have a class that implements an interface that inherits from IDisposable. But your specific class does not have any resources that need to be disposed. Then you could just derive form the Disposable base class to meet the IDisposable requirement in a way that allows anyone subclassing your class to handle unmanaged resources.

Leave a comment

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.