Arseny
Arseny

Reputation: 7351

What's a proper way to unsibscribe from events in c#?

I have a model class with an event which I subscribe from other classes. I want to subscribe and un-subscribe in each class correctly.

Upvotes: 4

Views: 516

Answers (4)

Jan Remunda
Jan Remunda

Reputation: 7930

You can also control subscriptions and unsubsriptions with this declaration. But you also have to iterate through dictionary and call manually subscribed delegates.

    private Dictionary<string, EventHandler> TestEvents { get; }

    public event EventHandler TestEvent
    {
        add
        {
            string name = value.GetType().FullName;
            if (!TestEvents.ContainsKey(name))
            {
                TestEvents.Add(name, value);
            }
        }
        remove
        {
            string name = value.GetType().FullName;
            if (TestEvents.ContainsKey(name))
            {
                TestEvents.Remove(name);
            }
        }
    }

Upvotes: 1

Peter
Peter

Reputation: 14098

If you want to guarantee you only unsubscribe once, you can use the GetInvocationList method:

if (_model.OnMyEvent != null && _model.GetInvocationList().Contains(EventHandle))
{
    _model.OnMyEvent -= EventHandle
}

But as mentioned by the others, you can unsubscribe multiple times. If this really isn't a problem, keep it that way. The solution I propose is just code-noise. Simply unsubscribing in one line is much neater, and easier to read when your class starts to grow.

Upvotes: 1

Matthias
Matthias

Reputation: 12259

You can safely unsubscribe the same handler from an event multiple times. Additional checking is not required and would be contraproductive.

Upvotes: 2

Marc Gravell
Marc Gravell

Reputation: 1062502

If you only subscribe once, it doesn't matter how many times you unsubscribe - unsubscribing when you don't have a subscription is a no-op. Equally, the entire point of the event API is that you can't accidentally unsubscribe other subscriptions (either other types, or other instances of the same type).

As such, the code as shown should be fine, although it might be worth moving the two calls to a single method that handles this. That might be overkill, though.

Also, if your type is IDisposable, make sure it gets called in that code-path too (presumably by calling Close()).

Upvotes: 11

Related Questions