The Inquisitive Coder – Davy Brion's Blog

Trying to walk that thin line between intelligence and ignorance

Disposing of the IDisposable implementation

Posted by Davy Brion on June 17th, 2008

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.

18 Responses to “Disposing of the IDisposable implementation”

  1. Ifeanyi Echeruo Says:

    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.

  2. Davy Brion Says:

    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?

  3. Rob Says:

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

  4. Davy Brion Says:

    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

  5. Rob Says:

    Maybe something like:


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

  6. Davy Brion Says:

    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

  7. Rob Says:

    and then we get drunk

  8. Davy Brion Says:

    :)

  9. Davy Brion Says:

    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

  10. Yoram Says:

    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.

  11. Davy Brion Says:

    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).

  12. Ayende Rahien Says:

    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

  13. Kevin Kerr Says:

    This should have had more kicks :)

  14. kilfour Says:

    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.

  15. Quantum Bit Designs » Blog Archive » A Thread-Safe IDisposable Base Class Says:

    [...] IDisposable (rarely) we have to look up the recommended pattern. Therefore he came up with an abstract base class that provides the proper plumbing and method signatures. All it takes is deriving from this [...]

  16. Quantum Bit Designs » Blog Archive » A Thread-Safe IDisposable Base Class Says:

    [...] IDisposable (rarely) we have to look up the recommended pattern. Therefore he came up with an abstract base class that provides the proper plumbing and method signatures. All it takes is deriving from this utility [...]

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

    [...] If you can, try to put this pattern into a reusable base class and make your Disposable Managed Resource holding types inherit from this. An example of this approach can be found here. [...]

  18. The Inquisitive Coder - Davy Brion’s Blog » Blog Archive » The Importance Of Releasing Your Components Through Windsor Says:

    [...] Disposing of the IDisposable implementation [...]

Leave a Reply

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>