Search code examples
c#.netdisposeidisposable

Where to call Dispose() of IDisposable created in constructor?


Where to call Dispose() for IDisposable objects owned by an object?

public class MyClass
{
    public MyClass()
    {
        log = new EventLog { Source = "MyLogSource", Log = "MyLog" };
        FileStream stream = File.Open("MyFile.txt", FileMode.OpenOrCreate);
    }


    private readonly EventLog log;
    private readonly FileStream stream;

    // Other members, using the fields above
}

Should I implement Finalize() for this example? What if I do not implement anything at all? Will there be any problems?

My first thought was that MyClass should implement IDisposable. But the following statement in an MSDN article confused me:

Implement IDisposable only if you are using unmanaged resources directly. If your app simply uses an object that implements IDisposable, don't provide an IDisposable implementation.

Is this statement wrong?


Solution

  • If MyClass owns an IDisposable resource, then MyClass should itself be IDisposable, and it should dispose the encapsulated resource when Dispose() is called on MyClass:

    public class MyClass : IDisposable {
        // ...
        public virtual void Dispose() {
            if(stream != null) {
                stream.Dispose();
                stream = null;
            }
            if(log != null) {
                log.Dispose();
                log = null;
            }
        }
    }
    

    No, you should not implement a finalizer here.

    Note: an alternative implemention might be something like:

    private static void Dispose<T>(ref T obj) where T : class, IDisposable {
        if(obj != null) {
            try { obj.Dispose(); } catch {}
            obj = null;
        }
    }
    
    public virtual void Dispose() {
        Dispose(ref stream);
        Dispose(ref log);
    }