将lambda表达式用于事件处理程序

Chr*_*cia 101 c# performance events lambda

我目前有一个声明如下的页面:

public partial class MyPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //snip
        MyButton.Click += (o, i) =>
        {
            //snip
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我最近才从1.1迁移到.NET 3.5,所以我习惯在Page_Load之外编写事件处理程序.我的问题是; 在使用lambda方法时,我应该注意哪些性能缺陷或缺陷?我更喜欢它,因为它当然更简洁,但我不想牺牲性能来使用它.谢谢.

And*_*are 102

由于编译器会将lambda表达式转换为等效的委托,因此没有性能影响.Lambda表达式只不过是一种语言特性,编译器将其转换为您习惯使用的完全相同的代码.

编译器会将您拥有的代码转换为以下内容:

public partial class MyPage : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        //snip
        MyButton.Click += new EventHandler(delegate (Object o, EventArgs a) 
        {
            //snip
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 需要注意的是,如果不保留对代理人的引用,则无法取消订阅该事件. (8认同)
  • “完全相同的代码”有点误导;至少在从封闭方法中引用局部变量时,lambda 表达式不会被转换为方法 * 和 * 类似于存储局部变量当前值的闭包对象。 (3认同)

Gab*_*abe 58

性能方面它与命名方法相同.当你执行以下操作时,最大的问题是:

MyButton.Click -= (o, i) => 
{ 
    //snip 
} 
Run Code Online (Sandbox Code Playgroud)

它可能会尝试删除不同的lambda,将原来的lambda留在那里.所以经验教训是,除非你也希望能够删除处理程序,否则它很好.

  • 如果你真的想使用lambda但需要删除事件,你可以随时保持对象在局部变量/字段中然后删除它,例如`var event =(o,e)=> doSomething(); handler + = event; doSomethingElse(); handler - = event;` (9认同)
  • "它可能会*尝试......"?它会*在这种情况下*删除正确的处理程序吗? (3认同)
  • @ORMapper:是的.如果编译器具有相同的语义(代码不必相同,但它们必须执行相同的操作)并且捕获相同的变量实例(不仅仅是相同的变量,但这些变量的实例相同).有关所有详细信息,请参阅C#规范的7.10.8节(委托相等运算符). (3认同)

小智 40

EventHandler handler = (s, e) => MessageBox.Show("Woho");

button.Click += handler;
button.Click -= handler;
Run Code Online (Sandbox Code Playgroud)

  • 不完全偏离主题,因为内存使用会导致性能下降. (3认同)
  • 在处理程序本身中删除自身也可能有所帮助:````#EventHandler handler = null; handler =(s,e)=> {MessageBox.Show("Woho"); button.Click - = handler;}``` (2认同)