0

Is there any difference between creating C# event handler like this:

btnHey.Click += new EventHandler(delegate (object obj, EventArgs evn) { System.Diagnostics.Debug.Write("Hey"); });

and this:

btnHey.Click += (object obj, EventArgs evn) => System.Diagnostics.Debug.Write("Hey");
jackhab
  • 17,128
  • 37
  • 99
  • 136
  • 3
    Does this answer your question? [Using lambda expressions for event handlers](https://stackoverflow.com/questions/2465040/using-lambda-expressions-for-event-handlers) – Hirasawa Yui Jan 26 '21 at 09:35
  • @HirasawaYui The question you refer to is about whether lambdas can be used for event handler (well, I know they can). I was interested to know whether there any differences between using a lambda and creating new delegate for an event. So Jon Skeet gives a very nice summary and clear answer – jackhab Jan 26 '21 at 13:53

1 Answers1

8

No, those are equivalent. There are actually six options to consider:

  • btnHey.Click += new EventHandler(delegate (object obj, EventArgs evn) { ... });
  • btnHey.Click += new EventHandler(MethodName);
  • btnHey.Click += delegate (object obj, EventArgs evn) { ... };
  • btnHey.Click += MethodName;
  • btnHey.Click += (object obj, EventArgs evn) => ...; (Expression-bodied lambda)
  • btnHey.Click += (object obj, EventArgs evn) => { ... }; (Statement lambda)

... where MethodName is the name of a method with an appropriate signature. The parameters to the lambda expression can also be inferred, leading to even more options...

There can be some subtle differences between them in terms of whether or not a new delegate object is actually created. The options using method group conversions (MethodName) will always create a new object, at least at the time of writing. With the other options, the compiler may be able to cache a delegate object and reuse it - depending on whether it captures this or local variables. That's almost never significant, but worth knowing in the rare cases where you need micro-optimization.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    Personally, I prefer the 4th (direct method name is short and intuitive as the old C style) and after (I like auto-typed lambdas), to the previous ones. –  Jan 26 '21 at 10:10
  • 1
    @OlivierRogier: Agreed. I've been trying to make it so the compiler can cache delegates created that way. First step is fixing the specification to allow it (I find it bizarre that `new` doesn't always mean new, but a method group conversion does). The ECMA C# 5 standard *does* allow for caching, and I'm trying to make sure that is maintained in later versions. Then we'll see whether the compiler team will actually use it :) – Jon Skeet Jan 26 '21 at 10:15
  • `btnHey.Click += (o, e) => {...}` seems to be an option as well – Pavel Anikhouski Jan 26 '21 at 12:00
  • 1
    @PavelAnikhouski: True - that's just "a lambda expression with implicitly typed parameters". Will note that. – Jon Skeet Jan 26 '21 at 12:00
  • While you're talking to the compiler team, could you please persuade them to allow a) open instance methods b) referring directly to a property getter or setter without reflection (the latter I use constantly to avoid dynamic functions) – Charlieface Jan 26 '21 at 13:05
  • @Charlieface: Those are *language* feature requests rather than *compiler* feature requests - I'd suggest filing issues in https://github.com/dotnet/csharplang – Jon Skeet Jan 26 '21 at 13:54
  • It will look better coming from you though https://github.com/dotnet/csharplang/issues/1385 They should just allow the hidden `get_PropertyName` as a method group. Funny thing is that `get_PropertyName` already leaks via a CS0082 compiler error – Charlieface Jan 26 '21 at 14:29
  • @Charlieface: No, I'm not going to start adding my support for proposals because people ask me to. That would just open me up for a deluge of requests. – Jon Skeet Jan 26 '21 at 14:33