Do I have to remove the handler
Asked Answered
A

1

6

the more I dig into C# and the GC I find more and more things I'm not quite sure about. I always thought that the Dispose and the respective Finalizer is only necessary when having some unmanaged resources in my classes.

But I have many occasions where there are only native C# classes where it is not quite clear to me if I need the Dispose and the respective Finalizer. For instance when I have event-handlers attached to my events.

Do I need to remove the event-handlers when I call Dispose. Also it was told to me that the object might not get collected if event-handlers are still attached. If this is the case the GC is somehow compromised.

Is it possible to summarize when and how I need to implement Dispose and Finalizer?

In fact I have more questions about this, but maybe an answer to this question could help me further.

Ain answered 16/3, 2015 at 18:26 Comment(4)
Related post: Is it bad to not unregister event handlers?Inclined
This might be helpful: #27995484. Short version: make sure to unhook event handlers hooked to events on long-lived objects; don't worry about unhooking event handlers on short-lived objects.Abramson
Also this, from Jon Skeet: Should I always disconnect event handlers in the Dispose method?Mccormac
Simple rule: you never need a finalizer. Finalization is the job of classes that know how to do it much better than you do, the SafeHandle classes. You need Dispose() if you have fields in your class of a type that are disposable. So you can call their Dispose() method in yours. Having to unsubscribe events in Dispose() is a pretty strong code smell.Stemson
B
4

To clear up your general question of when to do Dispose and Finalize:

If you have a field in your class that is a IntPtr (or some other kind of unmanaged resource, but a IntPtr is the most common) and it is your classes responsibility to clean up that resource then you need to implement a finalizer. In that finalizer you should deallocate whatever resource the IntPtr points too. If you don't have a IntPtr then the class you are holding on to should be handling its own finalization and would implement IDisposeable (see the next part)

If you have a field in your class that implements IDisposable and your class is responsible for cleaning up after that object your class should also implement IDisposable and in that dispose method you should call Dispose() on the object.

For event handlers, it is a matter of personal preference. You can, but it only matters if you do or not if the person who subscribed to the event messed up their code.

Unless you expect the publisher of the event to outlive the subscriber, there's no reason to remove the event handler...

I personally do not, but I do know some people who do. If you wanted to do it, the process is simply setting the event handler to null in your dispose method.

public sealed class Example : IDisposable 
{
    public EventHandler MyEvent;

    public void Dispose()
    {
        MyEvent = null;
    }
}

EDIT: And a good point that Hans Passant brought up in the comments: You never need a finalizer, if you have a unmanaged resource that would need a finalizer it should get wrapped up in a SafeHandle wrapper to handle the finalization for you. Once you do that the object just becomes another normal IDisposable you need to take care of in your .Dispose() method.

Bring answered 16/3, 2015 at 18:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.