0

C# 5 で、イベントからサブスクライブ解除するときの -= 演算子の動作は何ですか。

次のように、このアプリケーション ロジックでは、同じイベントを複数回サブスクライブすることが有効であるとします。

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

現在、3回購読しています。

次の 1 行のコードで登録解除した後:

Property_Saved -= Property_Saved_Handler;

サブスクリプションはいくつ残っていますか? 2? なし?...?

4

4 に答える 4

15

後は残り2本です。それぞれ-=が 1 つのサブスクリプションのみを削除します。少なくとも、通常のデリゲートだけを使用してイベントをサポートしている場合はそうです。

これは、実際にイベントを含まなくても簡単に確認できます。

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
}

しかし、通常、イベントは C# のシンタックス シュガーであるメソッドであるDelegate.Combineandに委譲するだけです。Delegate.Remove+=-=

イベントとデリゲートに関する私の記事には、組み合わせと削除で何が起こるかについての詳細が含まれています。

于 2016-10-12T18:43:13.343 に答える
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 に答える