#941 – Checking to See If Objects Are Disposable

If a type implements the IDisposable interface, you should always call the Dispose method on an instance of the class when you are done using it.  The presence of IDisposable indicates that the class has some resources that can be released prior to garbage collection.

Below is one pattern for checking to see if an object implements the IDisposable interface.

            Dog bob = new Dog("Bob", 5);
            if (bob is IDisposable)

You can also use the using statement to automatically call Dispose on an object when you’re done using it.

#673 – Types Used in using Statement Must Implement IDisposable

The using statement is a shortcut for a try/finally block where the Dispose method is automatically called on any objects instantiated as part of the using statement.

            using (StreamWriter sw = new StreamWriter(@"D:\Hi.txt"))
                sw.Write("Hi !");
            // StreamWriter.Dispose automatically called

Because the Dispose method is called automatically on all objects instantiated as part of the using statement, each object must belong to a type that implements IDisposable.  The example below leads to a compile-time error because Dog does not implement IDisposable and therefore does not have a Dispose method.

            using (Dog d = new Dog("Kirby", 15))

#429 – Use the Dispose Pattern for Deterministic Destruction

You can implement a finalizer in a class to explicitly release unmanaged resources before an object’s memory is freed.  Drawbacks of this approach include:

  • You don’t control when the object’s resources are cleaned up
  • A finalizer can’t make use of any other managed objects  (they may have already been finalized)

Another pattern for releasing unmanaged resources is for a class to implement the IDisposable interface by providing a Dispose method.  Dispose is meant to clean up the object’s resources when it’s called.  A client of the class can decide exactly when it wants to release the object’s resources (deterministic destruction).  Benefits of this pattern include:

  • Can release resources earlier, not waiting for finalization
  • Dispose logic can make use of other managed resources
    public class Dog : IDisposable
        public void Dispose()
            // Release unmanaged resources here

            // Note: need logic to prevent double disposal, etc.