C# で二重ディスパッチ?質問する

C# で二重ディスパッチ?質問する

この用語を聞いたり読んだりしたことはありますが、その意味がよくわかりません。

このテクニックはいつ、どのように使用すればよいでしょうか? 適切なコードサンプルを提供してくれる人はいますか?

ベストアンサー1

ビジター パターンは、オブジェクト指向の方法でダブル ディスパッチを実行する方法です。

これは、コンパイル時ではなく実行時に、特定の引数の型に基づいてどのメソッドを使用するかを選択する場合に便利です。

二重派遣は、複数派遣

オブジェクトで仮想メソッドを呼び出す場合、実際に呼び出されるメソッドは単一のオブジェクトの型によって異なるため、シングルディスパッチと見なされます。

ダブルディスパッチの場合、オブジェクトの型とメソッドの唯一の引数の型の両方が考慮されます。これはメソッドのオーバーロード解決に似ていますが、ダブルディスパッチでは引数の型がコンパイル時に静的に決定されるのではなく、実行時に決定される点が異なります。

マルチディスパッチでは、メソッドに複数の引数を渡すことができ、どの実装が使用されるかは各引数の型によって異なります。型が評価される順序は言語によって異なります。LISP では、各型を最初から最後までチェックします。

多重ディスパッチを持つ言語では、ジェネリック関数が使用されます。これは単なる関数宣言であり、型パラメータを使用するジェネリックメソッドとは異なります。

C#でダブルディスパッチを行うには単一のオブジェクト引数を持つメソッドを宣言し、特定の型を持つ特定のメソッドを宣言できます。

using System.Linq;  

class DoubleDispatch
{ 
    public T Foo<T>(object arg)
    { 
        var method = from m in GetType().GetMethods()
                   where    m.Name == "Foo" 
                         && m.GetParameters().Length==1
                         && arg.GetType().IsAssignableFrom
                                           (m.GetParameters()[0].GetType())
                         && m.ReturnType == typeof(T)
                   select m;

        return (T) method.Single().Invoke(this,new object[]{arg});          
    }

    public int Foo(int arg) { /* ... */ }

    static void Test() 
    { 
        object x = 5;
        Foo<int>(x); //should call Foo(int) via Foo<T>(object).
    }
}       

おすすめ記事