Disposing of the IDisposable implementation

19 commentsWritten on June 17th, 2008 by
Categories: Memory Management, Patterns, Performance

Everytime i need to implement the IDisposable interface i have to lookup the recommended way of doing so. That in itself is a bad sign, so i figured i might as well get rid of this by putting the implementation in a reusable base class, based on the officially recommended way:

    public abstract class Disposable : IDisposable
    {
        private bool disposed;
 
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
 
        protected void Dispose(bool disposing)
        {
            if (!disposed)
            {
                if (disposing)
                {
                    DisposeManagedResources();
                }
 
                DisposeUnmanagedResources();
                disposed = true;
            }
        }
 
        protected void ThrowExceptionIfDisposed()
        {
            if (disposed)
            {
                throw new ObjectDisposedException(GetType().FullName);
            }
        }
 
        protected abstract void DisposeManagedResources();
        protected virtual void DisposeUnmanagedResources() {}
    }

So now i can simply inherit from Disposable, and i just need to implement the two abstract methods. Here's a made up example to illustrate this:

    public class MyExpensiveResource : Disposable
    {
        private FileStream fileStream;
        private MemoryStream memoryStream;
 
        public MyExpensiveResource(string path)
        {
            fileStream = new FileStream(path, FileMode.Open);
            memoryStream = new MemoryStream();
        }
 
        public void DoSomething()
        {
            ThrowExceptionIfDisposed();
 
            // ... something
        }
 
        protected override void DisposeManagedResources()
        {
            if (fileStream != null) fileStream.Dispose();
            if (memoryStream != null) memoryStream.Dispose();
        }
    }

Obviously, you can't use the Disposable base class if you're already inheriting from another base class so in that case you'd still have to implement the IDisposable interface.

Update: Here's a thread-safe version of this idea.

  • Ifeanyi Echeruo

    Actually the method name DisposeExpensiveObjects is a bit misleading. Dispose is meant for releasing unmanaged resources; OS handles, network connections etc, they dont have to be expensive just outside the reach of the garbage collector.

  • http://davybrion.com Davy Brion

    well, you should dispose each object you contain that implements IDisposable… but yeah, there are a lot of classes that implement that interface without necessarily being that expensive so that name is not really correct.

    Maybe a simple DisposeObjects() would actually be better?

  • Rob

    I think there still has to be a better way. Maybe some AOP implementation?

  • http://davybrion.com Davy Brion

    is that a challenge? ;)

    seriously though, an AOP solution would be nice, but i don’t know how well that would work… you’d have to make your type implement the IDisposable interface (which is possible with the Composite aspect in Postsharp) but then in your aspect you’d have to be able to recognize which members you’d have to dispose. I’m not sure how you could do that without resorting to reflection, which i’d rather not use in a Dispose method

  • Rob

    Maybe something like:


    interface ICleanDisposable: IDisposable
    {
    void DisposeOjects();
    void ClearReferences();
    }

  • http://davybrion.com Davy Brion

    ah, so you’d have the type implement the ICleanDisposable interface instead of the IDisposable interface and then from the AOP aspect you’d reference the target class through the interface type and call the DisposeObjects() and ClearReferences() methods at the appropriate time?

    That would certainly avoid the multiple inheritance issue

  • Rob

    and then we get drunk

  • http://davybrion.com Davy Brion

    :)

  • http://davybrion.com Davy Brion

    Actually, that still won’t be perfect… if your type implements the ICleanDisposable interface, you’re still required to provide a Dispose method to fullfil the IDisposable requirements that ICleanDisposable brings with it.

    If the aspect implements the Dispose method, it won’t be known at compile time since postsharp weaves the aspect code in after it’s been compiled. So you wouldn’t be able to compile to code due to the missing required Dispose method

  • Yoram

    Here is how I see it:
    - the ICleanDisposable doesn’t inherit from IDisposable
    - the Disposable aspect implements the IDisposable interface on the aspected class (through a composite aspect with Postsharp)
    - In order to call the Dispose() method implemented by the aspect in your code, you will need to use the following method provided by Postsharp:

    K Post.Cast(T myObject)

    Using this method will allow your code to compile. At compilation-time, Postsharp will check if myObject (of type T) can really be casted to the K type (IDisposable in our case).

    The problem with this approach is that you can’t use the using pattern easily. With the following code:

    // Toto is a class implementing ICleanDisposable and which has the Disposable aspect
    using (var toto = Post.Cast(new Toto()))
    {
    // do something
    }

    you won’t be able to call specific methods on the toto instance, as it will be casted to IDisposable… I guess that if we resort to using an old-school try-finally, we could get it to work as expected, but at the cost of making the code less readable.

  • http://davybrion.com Davy Brion

    yeah… code readability is very important to me though, so that’s not a direction i’m willing to take :)

    inheriting from Disposable works pretty well for me so far… I always try to avoid large inheritance hierarchies, and i only use class inheritance where it makes sense to me. So i don’t often run into to the issue where i can’t inherit from Disposable. Unless i have to extend a type i don’t have the source to, but in those cases i prefer composition over inheritance (if possible).

  • http://www.ayende.com/Blog/ Ayende Rahien

    The full disposable semantics are only required if you are holding an unmanaged resource.
    If you are holding only managed resources, you don’t care about that, and can leave the GC to do all the work

  • http://blog.quantumbitdesigns.com Kevin Kerr

    This should have had more kicks :)

  • kilfour

    To avoid multiple inheritence one could use a nested class that calls the disposing methods in its parent class and return an instance of the nested class from a context initialising method. Some sort of interface is best defined for the class managing the resources, and an abstract baseclass for the nested class wouldn’t hurt either.
    Client code would change from :

    using(MyExpensiveResource resource = new MyExpensiveResource())
    {
    resource.DoSomething()
    }

    to :

    MyExpensiveResource resource = new MyExpensiveResource()
    using(resource.AccessResources())
    {
    resource.DoSomething()
    }

    AccessResources needs to initialise the resources and return an instance of the nested class that implements idisposable. MyExpensiveResource would probably change name to MyExpensiveResourceManager at this time, but we are discussing a case where the elegant Disposable solution doesn’t work.

  • Pingback: Quantum Bit Designs » Blog Archive » A Thread-Safe IDisposable Base Class

  • Pingback: Quantum Bit Designs » Blog Archive » A Thread-Safe IDisposable Base Class

  • Pingback: The Inquisitive Coder - Davy Brion’s Blog » Blog Archive » .NET Memory Management

  • Pingback: The Inquisitive Coder - Davy Brion’s Blog » Blog Archive » The Importance Of Releasing Your Components Through Windsor

  • Pingback: Code weave helper for the standard Dispose pattern? | FaceColony.org - Developers Network