5

What is the difference between following 2 ways of subscribing for an event?

receiver.ConfigChanged += Config_ConfigChanged;

receiver.ConfigChanged += new EventHandler(Config_ConfigChanged);

It seems that both of them work the same way but if so, what is the point of using the second one?

What about unsubscribing, will both following methods work also the same way?

receiver.ConfigChanged -= Config_ConfigChanged;

receiver.ConfigChanged -= new EventHandler(Config_ConfigChanged);
CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
kmalmur
  • 2,809
  • 3
  • 29
  • 37
  • 1
    possible duplicate of [+= new EventHandler(Method) vs += Method](http://stackoverflow.com/questions/2749868/new-eventhandlermethod-vs-method) – James Oct 13 '11 at 08:24
  • http://stackoverflow.com/questions/26877/c-event-handlers – Connell Oct 13 '11 at 08:26
  • They are identical. Code generators prefer the long form, you can use the short one. Note how confusing `-= new` looks. – H H Oct 13 '11 at 08:27
  • possible duplicate of [C#: Difference between ' += anEvent' and ' += new EventHandler(anEvent)'](http://stackoverflow.com/questions/550703/c-difference-between-anevent-and-new-eventhandleranevent) – nawfal Jul 06 '14 at 20:20

4 Answers4

13

The verbose way works in all versions of C#, the short way only in C# 2 and later. So I see no reason to use the long way nowadays.

There are some situations where you still need to use new DelegateType(methodGroup), but event subscribing isn't one of them. These situations usually involve generic type inference or method overloading.

Unsubscribing will work either way since it is based on value equality, not referential equality. If I recall correctly both the implicit conversion from a method group and the explicit new get translated to the same IL code. The implicit conversion is just syntax sugar.

CodesInChaos
  • 106,488
  • 23
  • 218
  • 262
2

Visual Studio's TAB event auto-complete always defaults to the .Net 1.0 way of doing things regardless of what edition of the framework you are using. You may find some people who are used to reading the older way of doing things. I only came across the less verbose way through using Resharper!

Here's an MSDN article on event subscription - it says exactly what @CodeInChaos just confirmed: http://msdn.microsoft.com/en-us/library/ms366768%28v=vs.80%29.aspx

james lewis
  • 2,486
  • 3
  • 24
  • 30
0

Correct me if i'm wrong, but i don't know if this works

receiver.ConfigChanged += new EventHandler(Config_ConfigChanged);
receiver.ConfigChanged -= new EventHandler(Config_ConfigChanged);

Since these are 2 different instances I think this would

var configChanged = new EventHandler(Config_ConfigChanged);
receiver.ConfigChanged += configChanged;
receiver.ConfigChanged -= configChanged;

But then again, why not just use

receiver.ConfigChanged += Config_ConfigChanged;
receiver.ConfigChanged -= Config_ConfigChanged;
Frederiek
  • 1,605
  • 2
  • 17
  • 32
  • You are, um, word (wrong?). The first example is special-cased by the event system and will work as desired. – Grokys Oct 13 '11 at 08:28
  • I have never looked this up, but I also always assumed this to be the case. If I ever need to remove an event, I always declare the instance of the EventHandler as a variable within that class, then I can remove that instance from the event. I actually do this a lot, and after reading this question, I've started to ask myself if I could've saved myself a lot of time. – Connell Oct 13 '11 at 08:30
  • 2
    The `-` operator on delegates doesn't use referential equality, so all of these work. Also I expect the C# compiler to translate the first and third code the the same IL. So technically it's not the event system doing any special casing, but `Delegate.Remove` using value equality instead of referential equality. This behavior naturally propagates to `event`s. – CodesInChaos Oct 13 '11 at 08:33
0

Ok so

receiver.ConfigChanged -= Config_ConfigChanged;

will clear out all event handlers that refer to that method.

var eventHandler = new EventHandler(Config_ConfigChanged); 

receiver.ConfigChanged += eventHandler;
receiver.ConfigChanged += new EventHandler(Config_ConfigChanged); 

receiver -= eventHandler;

will only clear out the one eventHandler.

You use the verbose way if you don't care about tracking the handler.

Dave Walker
  • 3,498
  • 1
  • 24
  • 25