The Dis­pose pat­tern is some­thing we’ve all seen before, and it’s so tried and tested most of us (espe­cially myself!) have been more than happy to apply with­out question.

Whilst read­ing var­i­ous blogs/articles I came across some dif­fer­ing opin­ion about this well known pat­tern and started to ques­tion what I had taken for granted myself.

After some more research and a ques­tion on the gold­mine of knowl­edge that is the Stack­Over­flow I have short­listed a few points you should con­sider when imple­ment­ing the stan­dard C# dis­pose pattern:

  1. if your object doesn’t hold any IDis­pos­able objects or unman­aged resources (DB con­nec­tion, for exam­ple) then you don’t need to imple­ment the IDis­pos­able or final­izer at all
  2. if your object doesn’t hold any unman­aged resources then don’t imple­ment a final­izer, the Garbage Col­lec­tor won’t attempt to final­ize your object (which has a per­for­mance hit) unless you have imple­mented a finalizer.
  3. don’t for­get to call Dis­pose() on each of the IDis­pos­able objects in the Dispose(bool) method.
  4. if your object holds unman­aged resources, clean them up in the final­izer with­out re-writing any of the cleanup code in the Dispose(bool) method already.

So for a sim­ple class with no unman­aged resources and a col­lec­tion of IDis­pos­able objects, your class might look some­thing like this:

public sealed class MyClass : IDisposable
{
     IList<MyObject> objects;  // MyClass holds a list of objects
     private bool _disposed;   // boolean flag to stop us calling Dispose(twice)

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

     private void Dispose(bool disposing)
     {
          if (!_disposed)
          {
               // call Dispose on each item in the list
               if (disposing)
               {
                    foreach (var o in objects)
                    {
                         // check if MyObject implements IDisposable
                         var d = o as IDisposable();
                         if (d != null) d.Dispose();
                    }
               }
          _disposed = true;
          }
     }
}

This is fairly sim­i­lar to the stan­dard C# Dis­pose pat­tern, the main dif­fer­ence being the lack of a final­izer because remem­ber, imple­ment­ing a final­izer will impact the per­for­mance of your type so don’t imple­ment it unless you need it.

Share

Leave a Reply