繁体   English   中英

lambda表达式的生命范围是什么?

[英]What is life scope of lambda expression?

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

这是我的问题:我有一个由lambda表达式订阅的button1.Click事件。 我不知道是否需要取消订阅(这是不容易的,因为它是匿名的)? 或者我不必,因为它与控件(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操作以捕获所有cleanup操作,如下所示:

        private Action cleanup = () => { };

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

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

当您完成表单后,您可以非常快速地进行清理:

        cleanup();

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM