2

lambda 表达式的生命周期是多少?

这是我的问题:我有一个button1.Click由 lambda 表达式订阅的事件。我不知道我是否需要取消订阅(这并不容易,因为它是匿名的)?或者我不必这样做,因为它与它所连接的控件(button1)的生命周期相同?

button1.Click += (s, e) => { /*Do something; */};
4

3 回答 3

4

由于 lambda 表达式与按钮相关联,只要按钮没有从内存中销毁,它就会存在。对于您的问题

我不知道我是否需要取消订阅(这并不容易,因为它是匿名的)?

Lambda 表达式可以保存到 EventHandler 委托中,这使您可以选择访问 lambda 和取消订阅事件。这里是代码。

    EventHandler myEvent= (s, e) => { /*Do something; */};  
    //Subscribe
    button1.Click += myEvent;
    //Unsubscribe
    button1.Click -= myEvent;

可能是关于这个主题的最好解释我应该退订事件吗?

于 2012-09-29T04:54:35.480 回答
4

由于所有正常的 CLR 对象导致委托的生命周期将由任何引用它的对象定义。在您的情况下,仅button1通过Click. 因此,它将与button1. 除非有特殊原因(即想将处理程序更改为另一个),否则您不需要做任何特别的事情来“释放”它。

于 2012-09-29T05:06:38.160 回答
2

通过使用局部变量捕获它,您可以轻松地保留对事件处理程序引用的引用。

        EventHandler click = (s, e) => { /* Do something; */ };

然后你可以像这样附加它:

        this.button1.Click += click;

清理可能有点棘手,因为它通常需要您创建一个类级别的变量来保存对处理程序的引用。这会导致代码分散在您的班级中。

但是,有一个相当简单的方法来处理它。进行类级别的cleanup操作来捕获所有清理操作,如下所示:

        private Action cleanup = () => { };

现在,您附加事件处理程序的代码可以很好地位于单个方法中,如下所示:

        EventHandler click = (s, e) => { /* Do something; */ };
        this.button1.Click += click;
        cleanup += () => this.button1.Click -= click;

完成表单后,您可以像这样快速进行清理:

        cleanup();

很酷的是,您可以将各种清理代码添加到此操作变量。

于 2012-09-29T05:23:42.323 回答