A Little Trick to Ensure that Dispose is Called

Typically trying to avoid finalizers, there is one place* where they come in handy. That place is making sure that all consumers of your objects call Dispose either explicitly or using the using construct. The trick is so simple -- there is no rocket science or otherwise involved.

Basically, the idea is that you in your class you have a Finalizer and the Dispose method. In your Dispose method, you do what you would normally do and you call GC.SuppressFinalize(this). All of this happens within a #if DEBUG ... #endif.

#region IDisposable Members

  public void Dispose()

  {

    ...

#if DEBUG

  GC.SuppressFinalize(this);

#endif

    ...

  }

#endregion 

 Obviously, you can have more statements and instructions in your Dispose. Your finalizer will look something like this:

#if DEBUG

  ~DisposableClass()

  {

  Debug.Assert(false, "Disposable object not disposed");

  }

#endif

Of course, the magic that makes this work is that if Dispose is ever invoked, the finalizer is never invoked. Conversely, if the finalizer is invoked, then Dispose was not. This is a great way to ensure that your disposable objects are actively disposed of and if they are not, then you are made aware of that fact with a loud fanfare.

I am imagining that you could probably do some more fancy tracking by recording the stack frame of the allocation and display that when your finalizer asserts false. I will leave this as an exercise for the reader**.

* There may be others, but with SafeHandle I can't think of many places where you would need to keep explicit track of unmanaged resources.

** Through all my years in university, I always hated when professors would leave interesting points as exercises left to the reader. If you are trying to drive a point, make sure that it is not left to chance if you get it across or not. However, I have waited many years to use that same sentence, so here it is.