你需要“;Unwre”;匿名函数lambda

本文关键字:函数 lambda Unwre | 更新日期: 2023-09-27 17:58:40

我的理解是,在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?

我的假设是否定的

你需要“;Unwre”;匿名函数lambda

是的,你需要(*),你需要这样做:

Object myObject = new Object();
EventHandler handler = (object sender, EventArgs e) => { };
myObject.Event += handler; //Wired
myObject.Event -= handler; //Unwired

有关解释,请参见此处。

(*)
你不需要因为垃圾收集而这么做。如果您不希望事件再调用您的处理程序,则需要执行此操作。

更新:
澄清一下:
您想要取消调用事件处理程序的唯一原因是定义事件处理程序对象可以被垃圾回收
想想下面的例子:

  • 您有一个带有事件BlackOut的类PowerSource
  • 您有一个类LightBulb,只要有电源,它就会打开。它有一个方法ConnectToPowerSource。该方法订阅所提供的PowerSourceBlackOut事件
  • 你有一个包含灯泡的集合

现在,简单地从列表中删除一个灯泡不会使其被垃圾收集,因为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;