使用Lambda在C#中取消事件挂钩

5

我经常遇到这样的情况:我想订阅一个事件,但我想使用Lambda表达式来实现:

public class Observable
{
    public event EventHandler SomethingHappened;

    public void DoSomething()
    {
        // Do Something...
        OnSomethingHappened();
    }
}

// Somewhere else, I hook the event
observable.SomethingHappened += (sender, args) => Console.WriteLine("Something Happened");

我遇到的问题是我不知道如何取消事件。由于lambda在幕后创建了一个匿名委托,因此我无法调用-=

现在,我可以创建一个方法:

private void SomethingHappened(object sender, EventArgs args)
{
    Console.WriteLine("Something Happened");
}

然后我可以随意挂接/取消挂接:

observable.SomethingHappened += SomethingHappened;
observable.SomethingHappened -= SomethingHappened;

但是我真的非常希望使用我的lambda函数。在更复杂的例子中,lambda函数非常方便。

我相信我已经没有什么办法了......但我想知道是否有人已经找到了一种方法来解决这个问题?


是的,请尝试这个链接:https://dev59.com/JnI-5IYBdhLWcg3wpaJ1#1747236 - Benjol
3个回答

10

你不能使用lambda表达式赋值给var,因此无法使用它。相反,你应该使用[delegate notation] (https://dev59.com/FnRA5IYBdhLWcg3w1BuW#805882),或者使用实际的事件类型而不是var。 - Ivan

8

不幸的是,没有很好的方法来解决这个问题。您只能选择以下两种选项之一:

  • 使用您所描述的方法
  • 将lambda分配给变量,并使用该变量添加/删除事件

有些情况下,第二个选项会很有用。谢谢。 - Brian Genisio
我一直使用第二种方法,从未考虑过使用lambda。 - Neil Trodden
3
第二种方法使用lambda表达式。 - Brian Genisio
一个例子会让这个答案更有用。 - Stephen Price

0

如果您知道您的代码是唯一连接事件的代码,将事件变量分配为null将删除所有委托(但如果您希望代码具有可扩展性,则可能是非常不好的形式)。

否则,您应该将lambda保留在单独的变量中,并使用它来取消连接事件。


您不能这样做。只有拥有事件的类才能将事件属性设置为null,Observable的客户端禁止这样做。如果该事件是多播委托,客户端可以设置为null,但是事件被禁止了。无论哪种情况,我都同意。这是不好的形式。 - Brian Genisio

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接