5

Possible Duplicate:
Using IDisposable to unsubscribe events

I've found myself implementing IDisposable on each class that handles events coming from objects not declared inside the class. For example:

public class Text
{
    public Text(ClassWithEvents c)
    {
        c.Event += EventHandler;
    }
}

In this situation I would declare the class Text as IDisposable and on the Dispose method I would remove the event handler to avoid having the object pinned on memory and other nasty stuff (like code executing on objects that should be dead).

I was wondering if there is a better way to do this as I don't like having too much disposable classes as they have to be "handled with care".

Community
  • 1
  • 1
Ignacio Soler Garcia
  • 21,122
  • 31
  • 128
  • 207
  • Detaching event handlers in a `Dispose` method is quite appropriate. I would suggest, however, that your constructor should be wrapped in a `try`/`finally` block, with the `try` block setting an `ok` flag on success, and the `finally` block calling `Dispose` if `ok` is not set (and you should hope any derived classes do likewise). The `Dispose` method will have to deal with the possibility that it might be called multiple times or be called on partially-constructed objects, but there isn't anything other remotely-standard pattern for cleaning objects that throw from within their constructor. – supercat Jun 04 '12 at 19:38
  • Note, btw, that while one could put the `Dispose` in a `catch` block, catching exceptions which one is going to neither resolve nor wrap is less than ideal. I really wish there were a standard mechanism for ensuring that constructor exceptions get handled. Among other things, such a mechanism would make it possible to safely construct `IDisposable` objects within field initializers. – supercat Jun 04 '12 at 19:42
  • Sometime ago I read (not sure where) that constructors never should throw. When you have an exception into a constructor you're not sure about the state of the object. Move all your code that can trow to a Init() method or alike. Anyway thanks for you words. – Ignacio Soler Garcia Jun 04 '12 at 20:02
  • @SoMoS: The question of whether or not a method should show an exception is not a hard one requiring judgment; it's can actually be answered easily: a method should throw an exception if its specified post-conditions cannot otherwise be met. The more difficult question is what conditions a method (or constructor) should guarantee will be met if it doesn't throw. A constructor which guarantees that any object that is returned without throwing an exception will be valid, will save consumers the effort of having to check newly-constructed objects for validity. – supercat Aug 03 '12 at 17:28
  • @SoMoS: There is, however, one annoying wrinkle--it can be very difficult for an `IDisposable` base class to ensure that it will get cleaned up if a derived-class constructor throws an exception; I don't know if it can be done in C# without using `ThreadStatic` variables. Of course, the real problem is not with the possibility of constructors throwing, but rather with the fact that there's no standard way for something like a `using` block to get access to--and `Dispose`--a partially-constructed object. – supercat Aug 03 '12 at 17:33

0 Answers0