18

In the MSDN Events Tutorial hooking up to events is demonstrated with the example:

// Add "ListChanged" to the Changed event on "List":
List.Changed += new ChangedEventHandler(ListChanged);
...
// Detach the event and delete the list:
List.Changed -= new ChangedEventHandler(ListChanged);

Where as I have been keeping a reference to the delegate. Example:

ChangedEventHandler myChangedEvent = new ChangedEventHandler(ListChanged);
List.Changed += myChangedEvent;
...
List.Changed -= myChangedEvent;

When I look at the MSDN example code, "-= new" just looks wrong to me. Why would this List have a reference to an event handler I just created?

Obviously I must be thinking about things the wrong way? Can I get a pointer to a technical explanation of how -= works, seeing how -= appears to not be using one.

jphofmann
  • 284
  • 3
  • 10
  • 1
    Related: http://stackoverflow.com/questions/7751247/c-sharp-why-shall-i-use-new-keyword-when-subscribing-for-an-event/7751271#7751271 – CodesInChaos Oct 24 '11 at 21:34

2 Answers2

20

Yes, this is confuzzling syntax. A delegate object must be created before the handler can be removed from the event. Which is why C# supports this syntax as well:

 List.Changed -= ListChanged;

which looks more logical. The compiler however still generates the exact same code. Under the hood, the MulticastDelegate.RemoveImpl() method iterates the invocation list and removes delegate objects from that list whose Target and Method properties match.

Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • Hans - are you saying that the new Delegate is not actually created when using the `-= new` syntax? (I still prefer the `-= Handler` syntax, I think it reads much better, but it's interesting to hear that the generated code is identical. Goes to show what a gap there can between what you right and what a modern compiler can generate!) – AAT Oct 24 '11 at 22:30
  • No, it definitely gets created. It doesn't get used for anything else but a comparison, finding a match with the original delegate you used when you subscribed the event. Which saves you from having to keep that one around. Nice. Just a wee bit of garbage is the price. – Hans Passant Oct 24 '11 at 23:08
10

Event unsubscribing uses value equality, not reference equality. So the newly created delegate matches the old one(both target object and method are the same) and thus removes the old delegate from the invocation list.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262