分配null是否从对象中删除所有事件处理程序?

Dor*_*hen 30 .net c# com delegates event-handling

我在班上定义了新成员

protected COMObject.Call call_ = null;
Run Code Online (Sandbox Code Playgroud)

该类具有我订阅的以下事件处理程序

call_.Destructed += new COMObject.DestructedEventHandler(CallDestructedEvent);
Run Code Online (Sandbox Code Playgroud)

将我的成员设置为null,如下所示删除事件处理程序?

call_ = null;
Run Code Online (Sandbox Code Playgroud)

或者我必须取消订阅 - =?

Azo*_*ous 30

是的,您应该使用重载-=来取消订阅活动.

简单地分配引用null将不会自动执行此操作.该对象仍将监听该事件.

  • @AndrasZoltan得分答案比这更高,这是非常错误的.尽管如此,这是正确的.主要的是`call_`中的对象没有设置为null,只有`call_`只是对它的一个引用,可能有其他的,实际上有(在事件处理程序本身).这一切都归结为我们不将对象设置为null,我们将引用设置为null. (6认同)
  • 这在很大程度上取决于带有事件的对象是否会立即被收集;如果是,那么确实不值得取消订阅。 (2认同)

VS1*_*VS1 8

在设置为null或处理对象之前,您应该始终通过 - =取消订阅事件处理程序(简单地将变量设置为null将不会取消订阅所有处理程序),如下面的MSDN摘录中所示:

要防止在引发事件时调用事件处理程序,只需取消订阅该事件即可.为了防止资源泄漏,在处置订阅者对象之前取消订阅事件非常重要.在取消订阅事件之前,发布对象中作为事件基础的多播委托具有对封装订阅者事件处理程序的委托的引用.只要发布对象保存该引用,您的订阅者对象就不会被垃圾回收.

在以下链接中解释Unsubscribing:

如何:订阅和取消订阅事件(C#编程指南)

更多信息:

为什么你应该总是取消订阅事件处理程序