是否可以从事件中取消订阅匿名方法?

如果我订阅了这样的活动:

void MyMethod()
{
    Console.WriteLine("I did it!");
}

MyEvent += MyMethod;

我可以像这样取消订阅:

MyEvent -= MyMethod;

但如果我使用匿名方式订阅:

MyEvent += delegate(){Console.WriteLine("I did it!");};

是否可以取消订阅此匿名方法?如果有,怎么做?


当前回答

在3.0中可以缩短为:

MyHandler myDelegate = ()=>Console.WriteLine("I did it!");
MyEvent += myDelegate;
...
MyEvent -= myDelegate;

其他回答

Action myDelegate = delegate(){Console.WriteLine("I did it!");};

MyEvent += myDelegate;


// .... later

MyEvent -= myDelegate;

只要保持对委托的引用。

下面是一个简单的解决方案,它从事件中删除所有分配的方法。还有匿名方法。

使用这段代码并调整名称。

if (MyEvent != null)
    foreach (Delegate del in MyEvent.GetInvocationList())
        MyEvent -= (EventHandler<MyEventHandlerType>)del;

示例使用

public class SomeClass
{
  public event EventHandler<NiceEventArgs> NiceEvent;

  public void RemoveHandlers()
  {
    if (NiceEvent != null)
      foreach (Delegate del in NiceEvent.GetInvocationList())
        NiceEvent -= (EventHandler<NiceEventArgs>)del;
  }
}

感谢hemme的回答,我把它作为灵感。

一个简单的解决办法:

只需将eventandle变量作为参数传递给自身。 事件,如果你的情况下,你不能访问原始创建的变量,因为多线程,你可以使用这个:

MyEventHandler foo = null;
foo = (s, ev, mehi) => MyMethod(s, ev, foo);
MyEvent += foo;

void MyMethod(object s, MyEventArgs ev, MyEventHandler myEventHandlerInstance)
{
    MyEvent -= myEventHandlerInstance;
    Console.WriteLine("I did it!");
}

有点蹩脚的方法:

public class SomeClass
{
  private readonly IList<Action> _eventList = new List<Action>();

  ...

  public event Action OnDoSomething
  {
    add {
      _eventList.Add(value);
    }
    remove {
      _eventList.Remove(value);
    }
  }
}

重写事件添加/删除方法。 保留这些事件处理程序的列表。 当需要时,清除它们并重新添加其他的。

这可能行不通,也不是最有效的方法,但应该能把工作完成。

在3.0中可以缩短为:

MyHandler myDelegate = ()=>Console.WriteLine("I did it!");
MyEvent += myDelegate;
...
MyEvent -= myDelegate;