1

これら2つのクラスの違いは何ですか? どちらが好ましいですか?

class MulticastExample
{
    delegate void ME();

    ME me;

    public MulticastExample()
    {
        ME a = new ME(() => Console.WriteLine("A"));
        ME b = new ME(() => Console.WriteLine("B"));

        me = a + b;
    }

    public void Run()
    {
        me();
    }
}

-

class ListExample
{
    delegate void LE();

    List<LE> le = new List<LE>();

    public ListExample()
    {
        LE a = new LE(() => Console.WriteLine("A"));
        LE b = new LE(() => Console.WriteLine("B"));

        le.Add(a);
        le.Add(b);
    }

    public void Run()
    {
        foreach (var x in le)
        {
            x();
        }
    }
}
4

2 に答える 2

1

最初の例を使用する必要があると思います。と言うと、「マルチキャスト」デリゲートのアイテムのリストをいつでも取得できることに注意してくださいme.GetInvocationList()。タイプMulticastExample.MEは からこのメソッドを継承しSystem.Delegateます。

に割り当て、a構文をb使用する必要がない場合。new同じデリゲートは次によって作成されます。

ME a = () => Console.WriteLine("A");

の各インスタンスMEは不変であり、固定長の呼び出しリストを持つことに注意してください。このリストには、少なくとも 1 つの項目が含まれていることが保証されています。

デリゲートを「追加」または「減算」(結合または削除) すると、元のインスタンスは変更されず (不変性)、新しいインスタンスが作成されます。

次のような「減算」の結果の場合:

ME c = b - a;

長さゼロのマルチキャスト デリゲートが生成され、新しいインスタンスは作成されず、null代わりに参照が返されます (つまり、cになりますnull)。したがって、次のnullように呼び出す前にチェックを忘れないでください。c();

代わりに使用することを選択した場合List<T>、1 つの違いは (おそらく今でList<>はおわかりのように) a が変更可能であるということです。また、.NETのすべてのデリゲート タイプは複数の項目の呼び出しリストを許可するList<>ため、 のメンバー自体がマルチキャストでないことを確認するのはユーザーの責任であることに注意してください。

最後に (しかし、ご存じだと思いますが) のようなデリゲート型MEは、他の型 (この場合はclass MulticastExample) 内にネストする必要はありませんが、もちろん、デリゲート型を の「実装の詳細」にしたい場合は問題ありません。含むクラス。

デリゲート型をジェネリック型にする予定がある場合、+.

于 2012-11-25T08:04:28.467 に答える
1

を使用MulticastExampleすると、1 回の呼び出しでmeすべてのメソッドが呼び出されますsubscribed。したがって、1 回の呼び出しで呼び出されます。abme

ではListExample、各デリゲートを個別に呼び出す必要があります。そのため、ループで実行していることを個別に呼び出すa必要bがありますforeach


abが同じ署名の単一のメソッドを参照する場合ListExampleは、冗長です。 を使用する必要がありますMulticastExample

于 2012-11-25T08:04:37.420 に答える