【问题标题】:Event from delegate vs lambda [duplicate]来自委托与 lambda 的事件 [重复]
【发布时间】:2021-01-26 09:32:02
【问题描述】:

像这样创建 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");

【问题讨论】:

  • 这能回答你的问题吗? Using lambda expressions for event handlers
  • @HirasawaYui 您提到的问题是关于 lambdas 是否可以用于事件处理程序(嗯,我知道他们可以)。我很想知道使用 lambda 和为事件创建新委托之间是否有任何区别。所以 Jon Skeet 给出了一个非常好的总结和明确的答案

标签: c# delegates


【解决方案1】:

不,它们是等价的。实际上有六个选项需要考虑:

  • 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) => ...;(表达式主体 lambda)
  • btnHey.Click += (object obj, EventArgs evn) => { ... };(语句 lambda)

... 其中MethodName 是具有适当签名的方法的名称。还可以推断 lambda 表达式的参数,从而产生更多选择...

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

【讨论】:

  • 就我个人而言,我更喜欢第 4 个(直接方法名称像旧的 C 风格一样短而直观)和之后的(我喜欢自动输入的 lambda)。
  • @OlivierRogier:同意。我一直在努力做到这一点,以便编译器可以缓存以这种方式创建的委托。第一步是修复规范以允许它(我觉得奇怪的是new 并不总是意味着新的,但方法组转换确实如此)。 ECMA C# 5 标准 does 允许缓存,我正在努力确保在以后的版本中维护它。然后我们将看看编译器团队是否会真正使用它:)
  • btnHey.Click += (o, e) => {...} 似乎也是一种选择
  • @PavelAnikhouski:是的——这只是“一个带有隐式类型参数的 lambda 表达式”。会注意到这一点。
  • 当您与编译器团队交谈时,您能否说服他们允许 a) 打开实例方法 b) 直接引用属性 getter 或 setter 而无需反射(我经常使用后者来避免动态函数)
猜你喜欢
  • 2017-06-26
  • 1970-01-01
  • 2012-08-27
  • 2021-10-06
  • 2011-01-17
  • 2017-11-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多