从方法而不是委托订阅和取消订阅?

时间:2014-10-15 14:43:46

标签: c# memory-leaks delegates event-handling

我知道您有时需要跟踪代表,以便可以正确取消订阅:

private EventHandler _handler;

public void Foo()
{
    if (_handler != null)
    {
        Something.SomeEvent -= _handler; // Unsubscribe old event
    }

    _handler = delegate(object sender, EventArgs args) { };;
    Something.SomeEvent += _handler;
}

但是,如果你改用一种方法,那还有必要吗?

public void CustomMethod(object sender, EventArgs args) { ... }

public void Foo()
{
    // Not sure how to unsubscribe only if it wasn't subscribed first?
    if (some way to check)
    {
        Something.SomeEvent -= CustomMethod;
    }

    Something.SomeEvent += CustomMethod;
}

2 个答案:

答案 0 :(得分:2)

不,没有必要。如果您始终订阅/取消订阅相同的方法(以委托的形式),那么您不需要跟踪订阅的实际委托实例。新的委托实例(由+#和 - =操作中的C#编译器为您隐式创建)被正确标识为相同,因此 - =操作将删除在+ =操作中添加的委托。

换句话说,Delegate类的相等不仅仅是"引用相等"。具有相同调用列表的两个完全不同的Delegate实例被视为相等。

答案 1 :(得分:1)

如果您想检查是否订阅了特定方法,可以使用GetInvocationList然后使用Linq:

var mInfo = typeof(SomeType).GetMethod("CustomMethod");

if(Something.SomeEvent.GetInvocationList().Any(x => x.Method == mInfo))
{

}