【问题标题】:Subscribing and unsubscribing from a method instead of a delegate?从方法而不是委托订阅和取消订阅?
【发布时间】:2014-10-15 14:43:45
【问题描述】:

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

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;
}

【问题讨论】:

  • 使用 SomeEvent.GetInvocationList() 方法检查哪些方法订阅了您的事件
  • 我会让专家说了算,但我认为两者之间没有什么区别。

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


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

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

    var mInfo = typeof(SomeType).GetMethod("CustomMethod");
    
    if(Something.SomeEvent.GetInvocationList().Any(x => x.Method == mInfo))
    {
    
    }
    

    【讨论】:

      猜你喜欢
      • 2012-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-14
      • 2021-05-15
      • 1970-01-01
      相关资源
      最近更新 更多