web-dev-qa-db-ja.com

単純なデリゲート(デリゲート)とマルチキャストデリゲート

多くの記事を読みましたが、通常作成する通常のデリゲートとマルチキャストデリゲートの違いについてはまだ明確ではありません。

public delegate void MyMethodHandler(object sender);
MyMethodHandler handler = new MyMethodHandler(Method1);
handler += Method2;
handler(someObject);

上記のデリゲートMyMethodHandlerは、これら2つのメソッドを呼び出します。ここで、マルチキャストデリゲートはどこに来ますか。複数のメソッドを呼び出すことができることを読みましたが、デリゲートに関する私の基本的な理解が正しくないことを恐れています。

61
A9S6

この記事 はそれをかなりよく説明しています:

delegate void Del(string s);

class TestClass
{
    static void Hello(string s)
    {
        System.Console.WriteLine("  Hello, {0}!", s);
    }

    static void Goodbye(string s)
    {
        System.Console.WriteLine("  Goodbye, {0}!", s);
    }

    static void Main()
    {
        Del a, b, c, d;

        // Create the delegate object a that references 
        // the method Hello:
        a = Hello;

        // Create the delegate object b that references 
        // the method Goodbye:
        b = Goodbye;

        // The two delegates, a and b, are composed to form c: 
        c = a + b;

        // Remove a from the composed delegate, leaving d, 
        // which calls only the method Goodbye:
        d = c - a;

        System.Console.WriteLine("Invoking delegate a:");
        a("A");
        System.Console.WriteLine("Invoking delegate b:");
        b("B");
        System.Console.WriteLine("Invoking delegate c:");
        c("C");
        System.Console.WriteLine("Invoking delegate d:");
        d("D");
    }
}
/* Output:
Invoking delegate a:
  Hello, A!
Invoking delegate b:
  Goodbye, B!
Invoking delegate c:
  Hello, C!
  Goodbye, C!
Invoking delegate d:
  Goodbye, D!
*/
73
Darin Dimitrov

C#仕様では、すべてのデリゲート型をSystem.Delegateに変換できる必要があると規定されています。実際、実装でこれを実装する方法は、すべてのデリゲート型がSystem.MulticastDelegateから派生し、System.Delegateから派生するということです。

それは明らかですか?それがあなたの質問に答えたかどうかわかりません。

47
Eric Lippert

「すべてのデリゲートインスタンスにはマルチキャスト機能があります。」 - http://msdn.Microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

「C#では、すべてのデリゲートタイプがマルチキャストをサポートしています」- http://msdn.Microsoft.com/en-us/library/orm-9780596516109-03-09.aspx

11
MikeM

少し明確にするために:Allデリゲートは、1つまたは複数のターゲットメソッドがあるかどうかに関係なく、クラスMulticastDelegateのインスタンスです。ランタイムは、単一のターゲットを持つ一般的なケースに向けて少し最適化されていますが、原則として、単一または複数のターゲットを持つデリゲート間に違いはありません。 (ターゲットが0のデリゲートはできませんが、1つ以上です。)

new MyMethodHandler(Method1)のようなデリゲートをインスタンス化するとき、単一のターゲット(_Method1_メソッド)でデリゲートを作成します。

複数のターゲットを持つデリゲートは、2つの既存のデリゲートを組み合わせて作成されます。結果のデリゲートには、ターゲットの合計が含まれます。デリゲートはDelegate.Combine()と明示的に組み合わせることができますが、例のように、既存のデリゲートで_+=_演算子を使用して暗黙的に結合することもできます。

デリゲートを順に呼び出すと、デリゲート内のすべてのターゲットが呼び出されます。したがって、この例では、handler(someObject);は2つのメソッド(_Method1_および_Method2_)を呼び出します。これら2つのターゲットでデリゲートを作成したためです。

5
JacquesB

他の人の答えに追加してすみませんが、デリゲートは追加された順に呼び出されると思いました。

「マルチキャストデリゲート」セクション

http://msdn.Microsoft.com/en-us/library/orm-9780596527570-03-04.aspx

4
Lea Yates