Disposable Pattern

Disposable Pattern

An unofficial pattern that Microsoft follows, for disposing of objects, is one where a class implements the IDisposable interface, along with it’s public Dispose method, and then adds a protected overload of Dispose with a boolean argument. The argument is just to get the overload to work, most of the time it seems to be ignored. This pattern also usually includes a protected property that tracks whether the object has been disposed of, or not. Finally, there is sometimes a destructor for the class, that calls SuppressFinalize on the garbage collector.

In typical Microsoft fashion, all of those steps are left up to the developer to implement and get right.

Well, alright, in all fairness, Microsoft did add a snippet for this sort of thing. That makes it all better, right?

Way back when this pseudo pattern was first introduced, I created a base class for encapsulating this sort of thing. Now, obviously, because this is a base class, it won’t work if you already have a base class – at least not in C#, since C# doesn’t allow multiple inheritance. So, in that case, run the snippet and move on, I guess.

If you can use my base class, and you want to, of course, it looks like this:

public abstract class DisposableBase : IDisposable
{
    protected bool IsDisposed { get; private set; }

    void IDisposable.Dispose()
    {
        if (!IsDisposed)
        {
            Dispose(true);
            GC.SuppressFinalize(this);
            IsDisposed = true;
        }
    }

    protected virtual void Dispose(
        bool disposing
        )
    {

    }
}

Not a whole lot going on here. Like I said at the beginning of this post, the class implements the IDisposable interface, including the Dispose method. There is a protected IsDisposed property, that tracks whether the object has been disposed of, or not. When Dispose is called, if the object hasn’t already been disposed. then the overloaded Dispose method is called – thereby giving derived types the ability to cleanup their resources. After that, the method calls SupressFinalize on the garbage collector and sets the IsDisposed property to true.

Using the class is easy:

public class MyClass : DisposableBase
{
   protected override void Dispose(bool disposing)
   {
      // TODO : put cleanup logic here.
   }
}

Nothing Earth shattering, but, easier than writing cleanup logic over and over …

This class is part of the CG.Core NUGET package. The source can be found HERE. The package itself can be found HERE.

Thanks for reading!

Photo by k worthington on Unsplash