7

シングルディスパッチの問題は、JavaやC#などの静的に型指定された言語を使用したコーディングに従事する人々にはほとんどよく知られています。基本的な考え方は次のとおりです。

receiver実行時ポリモーフィズムにより、たとえば次のタイプ(実行時タイプ)に応じて適切なメソッド呼び出しにディスパッチできます。

IAnimal mything = new Cat();
mything.chop();

mythingメソッド呼び出しは、の実行時型、つまり。に従って実行されますCat。これはシングルディスパッチ機能です(Java / C#に存在します)。

ここで、ランタイムタイプのレシーバーだけでなく、(複数の)引数のタイプでもディスパッチする必要がある場合は、少し問題が発生します。

public class MyAcceptor {  
    public void accept (IVisitor vst) {...}   
    public void accept (EnhancedConcreteVisitor vst) {...}  
}

2番目のメソッドは呼び出されません。これは、「consumer」コードでは、さまざまなタイプのオブジェクト(私の例では訪問者)を共通のスーパータイプまたはインターフェイスで処理する傾向があるためです。

動的型付けでは多重ディスパッチポリモーフィズムが可能であり、C#4.0にはその動的キーワードがあるためです;)

4

2 に答える 2

12

はい、動的型付けでは複数のディスパッチが可能です。いいえ、それを行うために独自の動的オブジェクトを作成する必要はありません。

自分たちで実装したいと思っていて、コードに大量の""テストを入れEnumerable.Count()たくないとします。if (source is IList)このように書くことができます:

public static class Enumerable
{
    public static int Count<T>(this IEnumerable<T> source)
    {
        dynamic d = source;
        return CountImpl(d);
    }

    private static int CountImpl<T>(ICollection<T> collection)
    {
        return collection.Count;
    }

    private static int CountImpl(ICollection collection)
    {
        return collection.Count;
    }

    private static int CountImpl<T>(string text)
    {
        return text.Length;
    }

    private static int CountImpl<T>(IEnumerable<T> source)
    {
        // Fallback
        int count = 0;
        foreach (T t in source)
        {
            count++;
        }
        return count;
    }
}

私はそれが良い考えだと言っているわけではありませんが、それはそれがどのように機能するかです:)

一部のタイプの呼び出しがあいまいになる可能性がある状況を導入しないように注意する必要があることに注意してください。これは、パラメーターにクラスを使用する場合の問題ではありませんが、1つのクラスで複数のインターフェースを実装できることを考慮してください。

于 2010-05-02T07:17:40.877 に答える
1

はい、任意に複雑なディスパッチを行うDLRタイプを作成できます。http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.aspxを確認してください

于 2010-05-02T06:01:24.317 に答える