hknghw
Last Updated: February 25, 2016
·
915
· keboo

Dispose the un-disposable

Sometimes you run accross an object, that is holding onto un-manged resources. It would be great if the creator would have simply implemented the IDisposable interface to make wrapping it in a using statement simple, but alas not all objects are created that way.

Here is an example of a wrapper class that will let you dispose any object. It is a nice example of using generic interfaces and Action delegates.

public static class DisposeWrapper
{
    public static IDisposeWrapper<T> Wrap<T>(T obj, Action<T> disposeAction) where T : class
    {
        if (obj == null) throw new ArgumentNullException("obj");
        if (disposeAction == null) throw new ArgumentNullException("disposeAction");

        return new InternalWrapper<T>(obj, disposeAction);
    }

    public static IDisposeWrapper<T> Wrap<T>(Action<T> disposeAction) where T : class, new()
    {
        if (disposeAction == null) throw new ArgumentNullException("disposeAction");

        return new InternalWrapper<T>(new T(), disposeAction);
    }

    private class InternalWrapper<T> : IDisposeWrapper<T> where T : class 
    {
        private readonly T _object;
        private readonly Action<T> _disposeAction;

        public InternalWrapper(T @object, Action<T> disposeAction)
        {
            _object = @object;
            _disposeAction = disposeAction;
        }

        T IDisposeWrapper<T>.Object
        {
            get { return _object; }
        }

        void IDisposable.Dispose()
        {
            _disposeAction(_object);
        }
    }
}

public interface IDisposeWrapper<T> : IDisposable
{
    T Object { get; }
}

And here is an example of its usage:

class Program
{
    static void Main()
    {
        //The first way to use the DisposableWrapper
        var myFoo = new NotDisposable();
        using(DisposeWrapper.Wrap(myFoo, x => x.Close()))
        {
            myFoo.DoSomething();
        }

        //The second way to use the DisposableWrapper
        using (var wrapper = DisposeWrapper.Wrap(new NotDisposable(), x => x.Close()))
        {
            wrapper.Object.DoSomething();
        }

        //The third way to use the DisposableWrapper
        using (var wrapper = DisposeWrapper.Wrap<NotDisposable>(x => x.Close()))
        {
            wrapper.Object.DoSomething();
        }

        Console.ReadLine();
    }
}

public class NotDisposable
{
    public void DoSomething()
    {
        Console.WriteLine("Do something called");
    }

    public void Close()
    {
        Console.WriteLine("Close called");
    }
}

Source: http://dotnetgeek.tumblr.com/post/32508564024/dispose-the-un-disposable

Say Thanks
Respond