lambda 表达式的生命周期是多少?
这是我的问题:我有一个button1.Click
由 lambda 表达式订阅的事件。我不知道我是否需要取消订阅(这并不容易,因为它是匿名的)?或者我不必这样做,因为它与它所连接的控件(button1)的生命周期相同?
button1.Click += (s, e) => { /*Do something; */};
由于 lambda 表达式与按钮相关联,只要按钮没有从内存中销毁,它就会存在。对于您的问题
我不知道我是否需要取消订阅(这并不容易,因为它是匿名的)?
Lambda 表达式可以保存到 EventHandler 委托中,这使您可以选择访问 lambda 和取消订阅事件。这里是代码。
EventHandler myEvent= (s, e) => { /*Do something; */};
//Subscribe
button1.Click += myEvent;
//Unsubscribe
button1.Click -= myEvent;
可能是关于这个主题的最好解释我应该退订事件吗?
由于所有正常的 CLR 对象导致委托的生命周期将由任何引用它的对象定义。在您的情况下,仅button1
通过Click
. 因此,它将与button1
. 除非有特殊原因(即想将处理程序更改为另一个),否则您不需要做任何特别的事情来“释放”它。
通过使用局部变量捕获它,您可以轻松地保留对事件处理程序引用的引用。
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();
很酷的是,您可以将各种清理代码添加到此操作变量。