11

次があるとします。

interface Foo 
{
 bool Func(int x);
}

class Bar: Foo
{
  bool Func(int x)
  {
   return (x>0);
  }  
}

class Baz: Foo
{
  bool Func(int x)
  {
   return (x<0);
  }  
}

これで、Bar と Baz を Foos として処理し、それらの Func メソッドを呼び出すことができます。

デリゲートはこれを少し単純化します。

delegate bool Foo(int x);

bool Bar(int x)
{
 return (x<0);
}

bool Baz(int x)
{
 return (x>0);
}

これで、Foo デリゲートとして Bar と Baz をいじることができます。

コードが短くなる以外に、デリゲートの本当の利点は何ですか?

4

10 に答える 10

14

わずかな違いがあります。デリゲートは、それらが定義されているクラスのメンバー変数にアクセスできます。C# では (Java とは異なり)、すべての内部クラスは静的であると見なされます。したがって、インターフェイスを使用してコールバックを管理している場合 (ボタンの ActionListener など)。実装する内部クラスには、(コンストラクターを介して) コールバック中に対話する必要がある可能性がある、含まれているクラスの部分への参照を渡す必要があります。デリゲートにはこの制限がないため、コールバックの実装に必要なコードの量が削減されます。

より短く、より簡潔なコードも価値のある利点です。

于 2008-09-18T19:29:00.100 に答える
6

ソフトウェア エンジニアリングの観点からすると、デリゲートは、関数インターフェイスのプロトタイプを作成するという点で、関数インターフェイスによく似ています。

必要なメソッドを含むクラス全体を渡す代わりに、デリゲートだけを渡すこともできます。これにより、大量のコードが節約され、はるかに読みやすいコードが作成されます。

さらに、ラムダ式の出現により、その場で簡単に定義できるようになりました。これは大きなメリットです。C# でオンザフライでクラスを構築することは可能ですが、実際には非常に面倒です。

両者の比較は興味深い概念です。ユースケースとコード構造の観点から、これらのアイデアがどれだけ似ているかは、これまで考えたことがありませんでした。

于 2008-09-18T19:29:56.667 に答える
3

デリゲートは、呼び出し元の観点から見ると、1 つのメソッドを持つインターフェイス参照と多くの共通点があります。

最初の例では、Baz と Bar はクラスであり、継承してインスタンス化できます。2 番目の例では、Baz と Bar がメソッドです。

インターフェイス コントラクトに一致するクラスだけにインターフェイス参照を適用することはできません。クラスは、インターフェイスをサポートすることを明示的に宣言する必要があります。署名に一致する任意のメソッドにデリゲート参照を適用できます。

インターフェイスのコントラクトに静的メソッドを含めることはできません。(ただし、拡張メソッドを使用して静的メソッドをボルトで固定することはできます)。デリゲート参照を使用して静的メソッドを参照できます。

于 2008-09-18T19:33:56.407 に答える
1

いいえ、デリゲートはメソッド ポインター用です。次に、デリゲートに関連付けられたメソッドの署名が正しいことを確認できます。

また、クラスの構造を知る必要はありません。このようにして、作成したメソッドを使用して別のクラスのメソッドに渡し、必要な機能を定義できます。

Find メソッドを使用した List<> クラスを見てください。これで、クラスに含まれるアイテムに IListFindable などを実装する必要なく、何かが一致するかどうかを決定するものを定義できるようになります。

于 2008-09-18T19:22:28.213 に答える
1

デリゲートを関数のパラメーターとして渡すことができます (技術的にはデリゲートはコンパイル時にオブジェクトになりますが、それはここでは重要ではありません)。(明らかに) オブジェクトをパラメーターとして渡すこともできますが、その場合、その型のオブジェクトをパラメーターとして関数に関連付けることになります。デリゲートを使用すると、どこから来たかに関係なく、同じ署名を持つコードで実行する関数を渡すことができます。

于 2008-09-18T19:23:20.037 に答える
1

デリゲートは、メソッドがデリゲートに適合するために必要な引数と戻り値の型を定義するメソッドのインターフェイスと考えることができます。

于 2008-09-18T19:24:35.383 に答える
0

Java にクロージャー (つまり、匿名デリゲート) を追加するための少なくとも 1 つの提案では、それらは単一のメンバー メソッドを持つインターフェイスと同等です。

于 2009-03-05T14:48:13.853 に答える
0

デリゲートは、型指定されたメソッド ポインターです。これにより、共変性と反変性を利用でき、オブジェクトの状態を変更できるため、インターフェイスよりも柔軟性が高くなります (インターフェイス ベースのファンクターで this ポインターを渡す必要があります)。

また、デリゲートには、それらを簡単に組み合わせるなどのことを可能にする、優れたシンタックス シュガーがたくさんあります。

于 2008-09-18T19:24:34.760 に答える
0

はい、デリゲートは 1 つのメソッドを持つインターフェイスと考えることができます。

于 2008-09-18T19:26:03.993 に答える
0

インターフェイスとデリゲートは 2 つのまったく異なるものですが、理解を容易にするためにインターフェイスのような用語でデリゲートを説明したくなる気持ちは理解できますが、真実を知らないと後で混乱する可能性があります。

デリゲートは、特定の目的には不十分な C++ メソッド ポインターの黒魔術に (部分的に) 触発されました。典型的な例は、メッセージ パッシングまたはイベント処理メカニズムの実装です。デリゲートを使用すると、クラスの型やインターフェイスの知識がなくてもメソッド シグネチャを定義できます。「void eventHandler(Event* e)」デリゲートを定義して、それを実装する任意のクラスで呼び出すことができます。

この古典的な問題と、デリゲートが望ましい理由についての洞察については、これを読んでから、これを読んでください。

于 2008-09-18T19:41:00.213 に答える