Mea culpa: the IsDisposed anti-pattern

Back a few years ago, when I was still a new-born at C# and .NET programming, I had found myself very proud for having improved the .NET framework itself. Indeed, I had just invented the IDisposableEx interface:

public interface IDisposableEx : IDisposable
{
     bool IsDisposed { get; }
}

What did I use this interface for? It seemed to me a great improvement to be able to know whether or not an object had been disposed. And I was writing code like this:

if (!myObject.IsDisposed) myObject.Dispose();

Here lie two style errors:

  1. Not so a serious one: why calling Dispose() when a using construct would make it perfectly useless (As of now, I only call Dispose() when the object is not instanciated in the method that will dispose it)?
  2. The real big one: what is the use of the test on the disposed state of the object? Microsoft clearly states that a Dispose() method call should NEVER EVER fail (see msdn). One could call Dispose() thousands of times, there should never happen any exception. So, the test is useless.

On the other hand, one could argue that testing the disposed state of the object isn’t that serious… and I agree with this; in fact, what is really misconcepted in the IDisposableEx interface is not how you use it, but what it supposes can happen inside the implementor: by allowing to test the disposed state, this interface suggests that the behavior of the Dispose() method depends on the state of the object. And even worse: if you call Dispose() and the IsDisposed property was true, then Dispose() might fail! And in some of my implementations, it did! In my mind providing a means of testing was good enough, and if your app ended with an uncaught exception, it was the developper’s fault: why didn’t you test IsDisposed?… my apologies go to them… 

The correct way to handle multiple calls to Dispose() is actually to store a disposed state, but it must be inner to the object and calling code must never rely on it (so I’d  better make this private, and remove the IDisposableEx interface – from source control if I can, so that no one ever discovers my crime):

private bool disposed = false;

public void Dispose()
{
    if (disposed) return;

    // disposing of allocated resources
    …
    // now, don’t forget to set the disposed state

    disposed = true;
}

I hope that having revealed a part of my dark past will help you not to make that mistake, or at least will it have made you laugh a bit.

 

PS: I can’t think of a scenario right now where a caller should be aware of the disposed state of the callee, but in such a case, the IsDisposed property seems acceptable (if you don’t want to catch numbers of ObjectDisposedException). But I think this would be a really bad idea to provide this property as part of an interface… Or at least should this interface be named something like IDisposedStateNotifier so that developpers don’t think it modifies the IDisposable.Dispose standard behavior…

4 thoughts on “Mea culpa: the IsDisposed anti-pattern

  1. Totally pent subject matter, appreciate it for selective information. dabkkbcbeede

Leave a comment