0

在 C# 5 中,取消订阅事件时 -= 运算符的行为是什么。

假设多次订阅同一个事件对该应用逻辑有效,如下:

Property_Saved += Property_Saved_Handler;
Property_Saved += Property_Saved_Handler;
Property_Saved += Property_Saved_Handler;

现在我们订阅了 3 次。

使用以下一行代码取消订阅后:

Property_Saved -= Property_Saved_Handler;

还剩多少订阅?2?没有任何?...?

4

4 回答 4

15

之后就剩下两个了。每个-=只删除一个订阅。至少,如果它仅使用常规委托来支持事件,情况就是如此。

您可以很容易地看到这一点,而无需真正涉及事件:

using System;

public class Program
{
    public static void Main(string[] args)
    {
        Action action = () => Console.WriteLine("Foo");
        // This is a stand-in for the event.
        Action x = null;
        x += action;
        x += action;
        x += action;
        x -= action;
        x(); // Prints Foo twice
    }
}

严格来说,事件订阅可以做任何事情。您可以实现这样的事件:

private EventHandler weirdEvent;
public event EventHandler WeirdEvent
{
    add { weirdEvent += value; } // Subscribe as normal
    remove { weirdEvent = null; } // I'm bored with *all* the handlers
}

但通常事件只是委托给Delegate.Combineand Delegate.Remove,它们是 C# 中的语法糖的+=方法-=

关于事件和委托的文章包含有关组合和删除的确切情况的更多详细信息。

于 2016-10-12T18:43:13.343 回答
3
private void button1_Click(object sender, EventArgs e)
{
  // set breakpoint
}

this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Click += new System.EventHandler(this.button1_Click);
this.button1.Click -= new System.EventHandler(this.button1_Click);

调用 click 事件将显示断点命中两次。

于 2016-10-12T18:46:15.337 回答
2

这也应该是安全的。

Property_Saved += Property_Saved_Handler;
Property_Saved -= Property_Saved_Handler;
Property_Saved -= Property_Saved_Handler;
于 2019-02-07T09:19:39.023 回答
1

只需使用自己的测试GetInvocationList

public delegate void MyEventHandler(string s);
public event MyEventHandler MyEvent;

MyEventHandler @event = s => { };

MyEvent += @event;
Console.WriteLine(MyEvent.GetInvocationList().Length);

MyEvent += @event;
Console.WriteLine(MyEvent.GetInvocationList().Length);

MyEvent -= @event;
Console.WriteLine(MyEvent.GetInvocationList().Length);

这将打印

1
2
1
于 2016-10-12T18:49:49.387 回答