28

I have the following code to let the GUI respond to a change in the collection.

myObservableCollection.CollectionChanged += ((sender, e) => UpdateMyUI());

First of all is this a good way to do this?

Second: what's the code to unsubscribe from this event? Is it the same but with -= (and then the complete anonymous method again)?

Gerrie Schenck
  • 22,148
  • 20
  • 68
  • 95

3 Answers3

38

First of all... yes its a good way of doing it, it's clean, small form and easy to read & understand... the caveat of course is "Unless you later want to unsubscribe".

I believe Jon Skeet pointed out before that "the specification explicitly doesn't guarantee the behaviour either way when it comes to equivalence of delegates created with anonymous methods."

So if you need to unsubscribe from the event at a later time, you'd be best to actually create a delegate instance so you can hang onto the reference for later.

var myDelegate = delegate(sender, e){UpdateMyUI()};

myObservableCollection.CollectionChanged += myDelegate;

myObservableCollection.CollectionChanged -= myDelegate;
Community
  • 1
  • 1
Eoin Campbell
  • 43,500
  • 17
  • 101
  • 157
  • var myDelegate = delegate(sender, e){UpdateMyUI()}; doesn't compile... you need to specify the delegate type. John Skeet uses Action delegate in his example but that takes only one argument. What delegate type should we use in your example? – Radu Simionescu Oct 06 '14 at 11:12
  • 1
    @RaduSimionescu: Same as the type of the event, which in this example would be `NotifyCollectionChangedEventHandler` – Ben Voigt Jan 16 '15 at 18:58
19

If you need to unsubscribe from an event, you need an instanced reference. Unfortunately, that means you can't use that particular syntax.

J. Steen
  • 15,470
  • 15
  • 56
  • 63
  • 2
    If by "that particular syntax" you mean creating the lambda and adding the handler in one line, then yeah. The simple solution is just storing a reference to the lambda. Really, I think the OP should be looking at using an ordinary method if he needs to reference it repeatedly - it improves readability, in my mind at least. – Noldorin Apr 30 '09 at 08:22
  • @Noldorin Yep, that's what I meant by "that particular syntax". And I totally agree with you. – J. Steen Feb 20 '13 at 09:36
1

It's an ok way to go, unless myObservableCollection is going to live longer than 'this', in which case you could end up with a memory leak, as the delegate which is created behind the scenes will conserve a reference to your 'this', which will keep it alive. If you are repeatedly creating and 'destroying' whatever is listening to the event, you will find that they aren't being collected by the garbage collector.

If this is a problem, you can go the route suggested in the answers, conserving a reference to the handler, which you must create first.

Another solution is to use weak references to create an event handler which will allow the subscriber to be collected if there are not other references. I've explored this solution in this question and answer.

Community
  • 1
  • 1
Benjol
  • 63,995
  • 54
  • 186
  • 268