JAL Computing

C++COMProgramming .NET Mac Palm CPP/CLI Hobbies

 

Home
Up

Chapter 28 "A Disposable Class"

In this brief chapter I present an abstract class Disposable that simplifies the implementation of the IDisposable interface. The IDisposable interface is normally implemented using the following idiom:

class Program : IDisposable
    {
        private bool disposed = false;
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this); // remove this from gc finalizer list
            Console.WriteLine("Dispose called.");
        }
        // call Dispose(true) from Dispose, call Dispose(false) from finalizer
        // dispose once only
        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing) // called from Dispose
                {
                    // Dispose managed resources.
                }
                // Clean up unmanaged resources here.
            }
            disposed = true;
        }
        ~Program() // maps to finalize
        {
            Dispose(false);
        }
 }

Personally I find the Dispose(bool disposing) idiom confusing which means error prone. I got tired of copying and pasting this idiom into classes that implement IDisposable so I wrote an abstract class Disposable:

    // I got tired of copy and pasting IDisposable
    public abstract class Disposable : IDisposable
    {
        protected bool disposed= false;
        // subclass needs to implement these two methods
        abstract protected void DisposeManagedResources();
        abstract protected void DisposeUnmanagedResources();
        public virtual void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        private void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                if (disposing) // called from Dispose
                {
                    DisposeManagedResources();
                }
                DisposeUnmanagedResources();
            }
            disposed = true;
        }
        ~Disposable() // maps to finalize
        {
            Dispose(false);
        }
    }

To use this class just inherit and implement the two abstract methods:

        abstract protected void DisposeManagedResources();
        abstract protected void DisposeUnmanagedResources();

Here is a class that extends from Disposable:

    // class that wraps unmanaged resource
    class Wrapper :  Disposable, IMyUnmanagedWrapper
    {
        protected override void DisposeManagedResources()
        {
            //Console.WriteLine("Disposed Managed Resources.");
        }
        protected override void DisposeUnmanagedResources()
        {
            Console.WriteLine("Disposed Unmanaged Resources.");
        }
        public void Draw() {
                if (disposed) { throw new ObjectDisposedException("Wrapper"); }
                // mimic some type of unmanaged action
                Console.WriteLine("Draw.");
        }
    }

Have fun!

Send mail to [email protected] with questions or comments about this web site. Copyright © 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 © 
Last modified: 08/04/09
Hosted by www.Geocities.ws

1