你需要“unwire”一个匿名函数/ lambda
我的理解是,用C#连接的任何事件处理程序都需要无线连接。
Object myObject = new Object(); myObject.Event += EventHandler; //Wired myObject.Event -= EventHandler; //Unwired
但是你需要取消以下代码吗? 如果是的话,怎么样?
Object myObject = new Object(); myObject.Event += (object sender, EventArgs e) => { }; //Wired myObject.Event -= ????? //Unwire? How?
我的假设是不是?
是的,你需要(*),你需要这样做:
Object myObject = new Object(); EventHandler handler = (object sender, EventArgs e) => { }; myObject.Event += handler; //Wired myObject.Event -= handler; //Unwired
请看这里的解释。
(*)
由于垃圾回收,您不需要这样做。 如果您不希望事件再次调用您的处理程序,则需要执行此操作。
更新:
澄清一下:
您想要取消事件处理程序的唯一原因是定义事件处理程序的对象可以被垃圾收集。
想想以下示例:
- 你有一个类
PowerSource
与事件BlackOut
。 - 只要有力量,你就有一个
LightBulb
类。 它有一个方法ConnectToPowerSource
。 此方法订阅所提供的PowerSource
的BlackOut
事件。 - 你有一个包含灯泡的集合
现在,只需从列表中删除一个灯泡就不会让它被垃圾收集,因为PowerSource
仍然在其BlackOut
事件中持有对LightBulb
实例的引用。 只有在从BlackOut
事件中取消注册LightBulb
后, LightBulb
才会收集垃圾。
是的,你必须这样做。 由于事件是强引用,因此将继续调用事件处理程序。
您可以按如下方式删除它:
EventHandler handler = (s,e) => { DoSomething(); } myObject.Event += handler; myObject.Event -= handler;
Object myObject = new Object(); EventHandler h = (object sender, EventArgs e) => { }; //Wired myObject.Event += h; myObject.Event -= h;
或者,在处理程序中取消连接:
Object myObject = new Object(); EventHandler h = null; //need to declare h to use it in the following line //compiler/resharper will complain about modified closure h = (object sender, EventArgs e) => { myObject.Event-=h; }; myObject.Event += h;