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

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

问题描述

可能显示的文件:结果
  在C#中结果退订匿名方法
  
我如何注销&lsquo的;匿名&rsquo的;事件处理程序

我最近发现,我可以使用lambda表达式创建简单的事件处理程序。我可以例如订阅像这样的单击事件:

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");

但是,你会怎么取消呢?

But how would you unsubscribe it?

推荐答案

在C#规范明确规定(IIRC),如果你有两个匿名函数(匿名方法或lambda前pressions),可能会或可能不会创造平等从code代表。 (两个代表相等,如果它们具有相等的目标和指相同的方法。)

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.)

当然,你需要记住你所使用的委托实例:

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前pression其删除自身,这是稍微麻烦 - 你需要参考的lambda前pression本身的委托,你不能做与简单的声明一个局部变量,并使用一个lambda前pression分配给它,因为这样的变量没有明确赋值。您通常解决这个获得通过先指定一个空值的变量:

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;

不幸的是它甚至不是容易封装到这一点的方法,因为事件不干净重新presented。你能来最接近的将是这样的:

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 实现,因为你必须创建一个新的事件处理程序 (这只是一个泛型类型参数)。可行的,但凌乱。

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天全站免登陆