デリゲートはどこで使用しますか?[閉まっている]


109

デリゲートを必要とする実際の場所は何ですか?この方法が最善の解決策である状況またはパターンが存在することに興味があります。コードは不要です。

回答:


33

デリゲートは、特定の種類のメソッドを定義する名前付きの型です。クラス定義が、それが定義する特定の種類のオブジェクトのすべてのメンバーをレイアウトするのと同様に、デリゲートは、定義する種類のメソッドのメソッドシグネチャをレイアウトします。

このステートメントに基づくと、デリゲートは関数ポインターであり、関数の外観を定義します。

デリゲートの実際のアプリケーションの優れた例は、述語です。リンクの例では、Array.Findが配列を検索に使用し、次に述語を使用して検索対象の基準を処理しています。この場合、Predicateシグネチャと一致するProductGT10メソッドを渡します。


154

「C#3.0の学習:C#3.0の基礎をマスターする」で述べたように

一般的なシナリオ: 国家元首が亡くなったとき、米国の大統領は通常、個人的に葬式に出席する時間がない。代わりに、彼はデリゲートを派遣します。多くの場合、この代理人は副大統領ですが、VPが不在の場合、大統領は国務長官やファーストレディなどの誰かを派遣する必要があります。彼は、委任された権限を1人に「固定」したくありません。彼は、この責任を、正しい国際プロトコルを実行できるすべての人に委任する可能性があります。

大統領は、どの責任が委任されるか(葬式に出席する)、渡されるパラメーター(お悔やみ、優しい言葉)、および彼が取り戻すことを望む値(善意)を事前に定義します。その後、大統領は、大統領の職務が進むにつれて、「実行時」にその委任された責任に特定の人物を割り当てます。

プログラミングのシナリオ: 特定のアクションを実行する必要がある状況に直面することがよくありますが、どのメソッド、またはどのオブジェクトでさえ、それを実行するために呼び出す必要があるか事前にわかりません。

例: ボタンは、通知する必要があるオブジェクトを認識していない場合があります。ボタンを特定のオブジェクトに関連付けるのではなく、ボタンをデリゲートに接続し、プログラムの実行時にそのデリゲートを特定のメソッドに解決します。


1
では、なぜ無名関数/ラムダを使用しないのですか?
Pacerier 2014年

5
@Pacerierこれは遅い応答であり、あなたは答えを発見したかもしれませんが、これを見つけた他の読者のために:匿名関数は一種のデリゲートです。
Anthony

10
@ Anthony + Pacerier:匿名メソッドはデリゲートではありません。無名メソッドはコードの一部です。デリゲートは、そのコードの一部を指すポインターです。デリゲートが指す匿名メソッドがないと、メソッドが呼び出されません。ラムダはラムダ式を作成するために使用される演算子です。ラムダ式は、主に匿名のメソッドを生成します。これは、デリゲートによってポイントされます。
Martin Mulder

ばかげていますが、ボタンが押されたときの使用法がわからない場合は、If ElseIfステートメントを作成します。ばかげて言った。
JustJohn 2016年

@Pacerier匿名メソッドはC#2.0で導入され、LambdaはC#3.0で導入されました。
AminM 2017年

18

ジェネリックリストのデリゲートの一般的な用途の1つは、1行のforeach操作を作成するためのアクションデリゲート(または匿名の同等のもの)を使用することです。

myList.Foreach( i => i.DoSomething());

また、述語デリゲートは、リストの検索またはプルーニングに非常に役立ちます。

myList.FindAll( i => i.Name == "Bob");    
myList.RemoveAll( i => i.Name == "Bob");

コードは不要だと言っていましたが、その有用性をコードで表現する方が簡単だと思います。:)


13

イベントをイベントハンドラーにバインドすることは、通常、デリゲートの最初の紹介です...デリゲートはEventHandlerクラスでラップされているため、イベントを使用していたことすら知らないかもしれません。


5

Delegateパターンが実際のコードでどのように使用されるかに興味がある場合は、Mac OS X上のCocoaをご覧ください。Cocoaは、Mac OS Xでのプログラミングに最適なAppleのUIツールキットであり、Objective Cでコーディングされています。各UIコンポーネントがサブクラス化やその他の手段ではなく、委任によって拡張されるように設計されています。

詳細については、デリゲートについてAppleが何を言っているかをこちらで確認することをお勧めします


5

win32 Pythonを使用するプロジェクトがありました。

さまざまな理由により、一部のモジュールはodbc.pyを使用してDBにアクセスし、他のモジュールはpyodbc.pyを使用しました。

両方の種類のモジュールで関数を使用する必要があるときに問題が発生しました。引数として接続オブジェクトが渡されましたが、時刻を表すためにdbi.dbiDateとdatetimeのどちらを使用するかを知る必要がありました。

これは、SQLステートメントの値としてodbc.pyがdbi.dbiDateとして日付が期待されるのに対し、pyodbc.pyは日時値が期待されるためです。

さらに複雑なのは、odbc.pyおよびpyodbc.pyによって作成された接続オブジェクトでは、追加のフィールドを設定できないことでした。

私の解決策は、odbc.odbc(...)およびpyodbc.pyodbc(...)によって返された接続オブジェクトをデリゲートクラスでラップすることでした。これには、追加のフィールドの値として目的の時間表現関数を含み、デリゲートします元の接続オブジェクトに対する他のすべてのフィールド要求。


5

あなたと同じ質問があり、このサイトに回答を求めました。

どうやら、私はこのスレッドの例をざっと見ても、それをよく理解していませんでした。

私が読んだところ、デリゲートの素晴らしい使用法を見つけました: http : //www.c-sharpcorner.com/UploadFile/thiagu304/passdata05172006234318PM/passdata.aspx

Formsは、POST / GET(QueryString)を使用したASP.NET Webサイトよりも値を渡すのがはるかに複雑であるため、これは新規ユーザーにはより明白に思えるかもしれません。

基本的には、「TextBox テキストをパラメーターとして受け取るデリゲートを定義します。

// Form1

// Class Property Definition
public delegate void delPassData(TextBox text);


// Click Handler
private void btnSend_Click(object sender, System.EventArgs e)
{
     Form2 frm= new Form2();
     delPassData del=new delPassData(frm.funData);
     del(this.textBox1);
     frm.Show();
}

//概要:デリゲートを定義し、新しいForm2クラスをインスタンス化し、funData()関数をデリゲートに割り当て、textBoxをデリゲートに渡します。フォームを表示します。

// Form2

public void passData(TextBox txtForm1)
{

     label1.Text = txtForm1.Text;
}

//概要:(デリゲートで定義されているように)TextBox txtForm1をパラメーターとして受け取り、ラベルテキストをtextBoxのテキストに割り当てます。

これがデリゲートでのいくつかの使用法を啓発することを願っています:) ..


Form2クラスメソッドの名前を(passDataではなく)funDataにするか、Form1関数の割り当ての名前を(frm.funDataの代わりに)frm.passDataにする必要があります。
18

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.