如何删除lambda事件处理程序 [英] How to remove a lambda event handler

查看:114
本文介绍了如何删除lambda事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


可能的重复:

取消订阅C#中的匿名方法

如何注销‘匿名’事件处理程序

我最近发现我可以使用lambdas创建简单的事件处理程序。我可以订阅一个这样的点击事件:

I recently discovered that I can use lambdas to create simple event handlers. I could for example subscribe to a click event like this:

button.Click += (s, e) => MessageBox.Show("Woho");

但是您如何取消订阅?

推荐答案

C#规范明确声明(IIRC)如果您有两个匿名函数(匿名方法或lambda表达式),它可能会也可能不会从该代码创建相等的代理。 (如果两个代表具有相同的目标并参考相同的方法,两个代表是相等的。)

The C# specification explicitly states (IIRC) that if you have two anonymous functions (anonymous methods or lambda expressions) it may or may not create equal delegates from that code. (Two delegates are equal if they have equal targets and refer to the same methods.)

可以肯定,你需要记住你使用的委托实例: / p>

To be sure, you'd need to remember the delegate instance you used:

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

button.Click += handler;
...
button.Click -= handler;

(我找不到规格的相关位,但我会很惊讶看到C#编译器积极地尝试创建平等的代理,依靠它是一个不明智的选择。)

(I can't find the relevant bit of the spec, but I'd be quite surprised to see the C# compiler aggressively try to create equal delegates. It would certainly be unwise to rely on it.)

如果你不想这样做,你会需要提取一个方法:

If you don't want to do that, you'll need to extract a method:

public void ShowWoho(object sender, EventArgs e)
{
     MessageBox.Show("Woho");
}

...

button.Click += ShowWoho;
...
button.Click -= ShowWoho;

如果要创建一个使用lambda表达式去除自身的事件处理程序,那么稍微复杂一点需要引用lambda表达式本身的代理,而不能用简单的声明一个局部变量并使用lambda表达式赋值给它,因为这个变量没有被明确赋值。你通常会通过为变量赋值一个空值:

If you want to create an event handler which removes itself using a lambda expression, it's slightly trickier - you need to refer to the delegate within the lambda expression itself, and you can't do that with a simple "declare a local variable and assign to it using a lambda expression" because then the variable isn't definitely assigned. You typically get around this by assigning a null value to the variable first:

EventHandler handler = null;
handler = (sender, args) =>
{
    button.Click -= handler; // Unsubscribe
    // Add your one-time-only code here
}
button.Click += handler;

不幸的是,将它封装到一个方法中并不容易,因为事件没有被干净地表示。最接近你会是这样的:

Unfortunately it's not even easy to encapsulate this into a method, because events aren't cleanly represented. The closest you could come would be something like:

button.Click += Delegates.AutoUnsubscribe<EventHandler>((sender, args) =>
{
    // One-time code here
}, handler => button.Click -= handler);

即使在 Delegates.AutoUnsubscribe 因为你必须创建一个新的 EventHandler (这只是一个通用的类型参数)。可行,但凌乱。

Even that would be tricky to implement within Delegates.AutoUnsubscribe because you'd have to create a new EventHandler (which would be just a generic type argument). Doable, but messy.

这篇关于如何删除lambda事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆