30

単一および複数のディスパッチとは何かを正確に理解しようとしています。

私はちょうどこれを読みました:
http://en.wikipedia.org/wiki/Multiple_dispatch

そして、その定義から、呼び出すオーバーロードの選択はコンパイル時に行われますが、C# と VB.Net は複数ディスパッチであると思われます。

私はここで正しいですか、それとも何か不足していますか? ありがとう!

4

8 に答える 8

47

OK、関数のオーバーロードが多重ディスパッチとは異なる微妙な違いを理解しました。

基本的に、違いは、呼び出すメソッドが実行時に選択されるか、コンパイル時に選択されるかです。さて、誰もがこれを言っていることは知っていますが、C#が静的に型付けされており、多重ディスパッチ言語(少なくとも私には)が動的に型付けされているように見えることを考えると、明確な例がなければ、これは非常に明白に聞こえます。これまでのところ、その定義だけで、多重ディスパッチと関数のオーバーロードはまったく同じように聞こえました。

これが実際に違いを生むのは、パラメータのタイプが異なるメソッドのオーバーロードが2つあるが、2つのタイプがポリモーフィックであり、次のオブジェクトを持つ上位タイプとして宣言された参照を使用して呼び出す場合です。下のタイプ...(誰かがこれを表現するためのより良い方法を考えることができるなら、この答えを自由に編集してください)

例:

int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}

void Main() { 
  IRebelAllianceShip theShip = new XWing();
  CaptureSpaceShip(theShip);
}

XWingは明らかにIRebelAllianceShipを実装しています。この場合、最初のメソッドが呼び出されますが、C#が多重ディスパッチを実装している場合は、2番目のメソッドが呼び出されます。

ドキュメントの再ハッシュについて申し訳ありません...これは、各ディスパッチメソッドの定義を読むだけでなく、この違いを説明する最も明確な方法のように思えます。

より正式な説明については、http: //en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_is_more_than_function_overloading

于 2009-01-27T14:42:51.930 に答える
25

For those that find this article using a search engine, C# 4.0 introduces the dynamic keyword. The code would look like the following.

int CaptureSpaceShip(IRebelAllianceShip ship) {}
int CaptureSpaceShip(XWing ship) {}

void Main() {   
    IRebelAllianceShip theShip = new XWing();  
    CaptureSpaceShip((dynamic)theShip);
}
于 2011-06-14T15:42:38.467 に答える
6

C# はシングル ディスパッチですが、マルチメソッドをエミュレートしようとしているように見えるタイトルのブログ投稿がいくつかあります。記事の 1 つを読み込むことができれば、ここで回答を更新します。

于 2009-01-26T14:29:32.160 に答える
4

動的キーワードを使用した複数のディスパッチの良い C# の例に興味がある人がいるかもしれません( MSDN ブログ) 。

class Animal 
{ 
}

class Cat : Animal 
{ 
}

class Dog : Animal 
{ 
}

class Mouse : Animal 
{ 
}

同じメソッドの複数のオーバーロードを作成し、それらのパラメータ タイプのさまざまな組み合わせに従って特殊化できます。

void ReactSpecialization(Animal me, Animal other) 
{ 
    Console.WriteLine("{0} is not interested in {1}.", me, other); 
}

void ReactSpecialization(Cat me, Dog other) 
{ 
    Console.WriteLine("Cat runs away from dog."); 
}

void ReactSpecialization(Cat me, Mouse other) 
{ 
    Console.WriteLine("Cat chases mouse."); 
}

void ReactSpecialization(Dog me, Cat other) 
{ 
    Console.WriteLine("Dog chases cat."); 
}

そして今、魔法の部分:

void React(Animal me, Animal other) 
{ 
    ReactSpecialization(me as dynamic, other as dynamic); 
}

これは、ReactSpecialization(Animal, Animal) を呼び出すだけでなく、C# コンパイラに各パラメーターの型を動的に調べて、どのメソッド オーバーロードを呼び出すかを実行時に選択するよう指示する "as dynamic" キャストによって機能します。

それが実際に機能することを証明するには:

void Test() 
{ 
    Animal cat = new Cat(); 
    Animal dog = new Dog(); 
    Animal mouse = new Mouse();

    React(cat, dog); 
    React(cat, mouse); 
    React(dog, cat); 
    React(dog, mouse); 
}

出力:

Cat runs away from dog.
Cat chases mouse.
Dog chases cat.
Dog is not interested in Mouse.

ウィキペディアによると、C# 4.0 (動的) は「複数ディスパッチ」言語です。
また、Java、C# (4.0 より前)、C++ などの言語はシングル ディスパッチだと思います。

于 2015-01-18T11:56:17.007 に答える
2

C# は複数のディスパッチをサポートしていません。ビジター デザイン パターンは、アルゴリズムを階層から分離することに重点が置かれているにもかかわらず、複数のディスパッチとして説明できるものをエミュレートします。

于 2009-01-26T14:38:25.433 に答える
1

引用されたウィキペディアの記事によると、多重ディスパッチは、定義上、関連するオブジェクトのランタイムタイプに基づいているため、C#とVB.netは、コンパイル時に決定が行われるため、これを使用しません。 。

于 2009-01-26T17:47:59.670 に答える
0

これは古い質問であることを理解しています..

.Net 4.0 では、複数のメソッドにキーワードを使用できますdynamic....Net 4.0 の例については、次をご覧ください。既存の「if」条件と「is」演算子をリファクタリングするための最適化されたコード

于 2014-01-22T14:13:03.720 に答える
0

GoF ビジター パターンは、ダブル ディスパッチを行う方法の例です。Scott Meyers の「より効果的な C++」では、C++ でそれを行う方法が示されています。これは、Java と C++ の両方でダブル ディスパッチを行う方法について説明している Dobbs 博士からのリンクです。

于 2009-01-26T14:36:28.993 に答える