可以使用以下构造声明事件:
public class MyClass
{
public event EventHandler<EventArgs> SomeEvent = (s,e) => {};
public void SomeMethod ()
{
// Do something interesting... ;)
SomeEvent (this, new EventArgs);
}
}
这允许在不需要检查事件是否为空的情况下引发事件。
现在,假设一个对象A持有对MyClass对象的引用,为该事件注册,然后在以后取消注册。
var myClass = new MyClass();
myClass.SomeEvent += MyHandler;
...
myClass.SomeEvent -= MyHandler;
myClass = null;
即使事件中仍存在no-op lambda表达式,GC是否会收集myClass?
我想是的,因为对象根不再被其他对象引用了...任何人都可以确认或证明不是吗?
答案 0 :(得分:6)
即使您没有删除“真正的”处理程序,也可以收集MyClass
的实例。
事件的正常“泄漏”是事件发布者(在这种情况下为MyClass
)通过订阅的事件处理程序引用另一个对象。事件不会阻止发布者被垃圾回收。无操作的lambda肯定对此没有影响。
答案 1 :(得分:3)
使用问题中的代码,即使您没有取消订阅,GC也会收集myClass。这种关系是另一种方式。 MyClass的事件保留了对订阅者的引用,因此理论上您应该担心订阅者不被收集。如果您取消订阅,将收集订阅者。