C# 来自代理vs lambda的事件

C# 来自代理vs lambda的事件,c#,delegates,C#,Delegates,像这样创建C#事件处理程序有什么区别吗: btnHey.Click += new EventHandler(delegate (object obj, EventArgs evn) { System.Diagnostics.Debug.Write("Hey"); }); 这是: btnHey.Click += (object obj, EventArgs evn) => System.Diagnostics.Debug.Write("Hey");

像这样创建C#事件处理程序有什么区别吗:

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

btnHey.Click += (object obj, EventArgs evn) => System.Diagnostics.Debug.Write("Hey");

不,那些是相等的。实际上有六种选择需要考虑:

  • btnHey.Click+=neweventhandler(委托(对象obj,EventArgs evn){…})
  • btnHey.Click+=neweventhandler(MethodName)
  • btnHey.Click+=delegate(objectobj,EventArgs evn){…}
  • btnHey.Click+=MethodName
  • btnHey.Click+=(对象对象,事件参数evn)=>(表达体lambda)
  • btnHey.Click+=(objectobj,EventArgs evn)=>{…}(语句lambda)
。。。其中
MethodName
是具有适当签名的方法的名称。也可以推断lambda表达式的参数,从而产生更多选项


就是否实际创建了新的委托对象而言,它们之间可能存在一些细微的差异。使用方法组转换的选项(
MethodName
)将始终创建一个新对象,至少在编写时是这样。使用其他选项,编译器可能能够缓存委托对象并重用它—这取决于它捕获的是
还是局部变量。这几乎没有什么意义,但在极少数需要微优化的情况下值得知道。

这是否回答了您的问题@HirasawaYui您提到的问题是关于lambdas是否可以用于事件处理程序(我知道它们可以)。我想知道使用lambda和为事件创建新委托之间是否有任何区别。因此,Jon Skeet给出了一个非常好的总结和清晰的回答。就我个人而言,我更喜欢第四个(直接方法名称与旧的C风格一样简短直观)和第四个(我喜欢自动键入的lambdas),而不是前几个。@OlivierRogier:同意。我一直在努力使编译器能够缓存以这种方式创建的委托。第一步是修改规范以允许它(我觉得奇怪的是,
new
并不总是意味着新的,但是方法组转换却意味着新的)。ECMA C#5标准确实允许缓存,我正在努力确保在更高版本中维护缓存。然后我们将看到编译器团队是否会实际使用它:)
btnHey.Click+=(o,e)=>{…}
似乎是一个选项well@PavelAnikhouski:True-这只是“具有隐式类型参数的lambda表达式”。当你与编译器团队交谈时,你能说服他们允许a)开放实例方法b)无反射地直接引用属性getter或setter(我经常使用后者来避免动态函数)