回答:
デリゲートは「関数へのポインタ」と考えるのが好きです。これはC日までさかのぼりますが、アイデアはまだ保持されます。
アイデアは、コードの一部を呼び出すことができる必要があるということですが、これから呼び出すコードの一部は、実行時までわかりません。したがって、その目的で「デリゲート」を使用します。デリゲートは、たとえば、イベントハンドラーなどのさまざまなイベントに基づいてさまざまなことを行う場合に便利です。
ここにあなたが見ることができるC#のリファレンスがあります:
たとえば、C#では、実行したい計算があり、実行時までわからない別の計算方法を使用したいとします。したがって、次のような計算方法がいくつかあるかもしれません。
public static double CalcTotalMethod1(double amt)
{
return amt * .014;
}
public static double CalcTotalMethod2(double amt)
{
return amt * .056 + 42.43;
}
次のようにデリゲートシグネチャを宣言できます。
public delegate double calcTotalDelegate(double amt);
次に、デリゲートをパラメータとして受け取るメソッドを次のように宣言できます。
public static double CalcMyTotal(double amt, calcTotalDelegate calcTotal)
{
return calcTotal(amt);
}
そしてCalcMyTotal
、使用したいデリゲートメソッドを渡すメソッドを呼び出すことができます。
double tot1 = CalcMyTotal(100.34, CalcTotalMethod1);
double tot2 = CalcMyTotal(100.34, CalcTotalMethod2);
Console.WriteLine(tot1);
Console.WriteLine(tot2);
Foo
デリゲートにして呼び出すthis.Foo()
関数ポインタを行うようにではなく、静的な関数を(Cで、あなたは多くの場合、余分な持っているvoid*
にパラメータをthis
関数ポインタに渡す)
デリゲートは単に関数ポインタです。
デリゲートを実行するメソッドを割り当てるだけです。その後、コードでInvokeを介してそのメソッドを呼び出すことができます。
デモするコード(これはメモリから書き込んだため、構文がオフになっている可能性があります)
delegate void delMyDelegate(object o);
private void MethodToExecute1(object o)
{
// do something with object
}
private void MethodToExecute2(object o)
{
// do something else with object
}
private void DoSomethingToList(delMyDelegate methodToRun)
{
foreach(object o in myList)
methodToRun.Invoke(o);
}
public void ApplyMethodsToList()
{
DoSomethingToList(MethodToExecute1);
DoSomethingToList(MethodToExecute2);
}
Qデリゲートとは何ですか?
Aオブジェクトがリクエストを受信すると、オブジェクトはリクエスト自体を処理するか、リクエストを2番目のオブジェクトに渡して作業を実行できます。オブジェクトが要求を渡すことを決定した場合、そのオブジェクトは、要求を処理する責任を2番目のオブジェクトに転送したと言います。
または、簡単な疑似例として、何かがobject1にリクエストを送信します。次に、object1はリクエストと自身をobject2-デリゲートに転送します。object2はリクエストを処理し、いくつかの作業を行います。(注:上記のリンクは良い例です)
デリゲートは、コマンドパターンの簡略化された実装と考えてください。
デリゲートは、メソッドを参照できるオブジェクトです。したがって、デリゲートを作成すると、メソッドへの参照を保持できるオブジェクトが作成されます。さらに、この参照を通じてメソッドを呼び出すことができます。したがって、デリゲートは、参照先のメソッドを呼び出すことができます。デリゲートの主な利点は、メソッドへの呼び出しを指定できることですが、実際に呼び出されるメソッドは、コンパイル時ではなく実行時に決定されます。
単純なデリゲート
Declaration of delegate:
delegate-modifier delegate return-type delegate-name(parameters)
Implementation of delegate:
Delegate-name delegate-object=new Delegate-name(method of class)
ここでは、デリゲート、マルチキャストデリゲート、およびそれらの使用法について説明します。デリゲートは、オブジェクト内のメソッド参照を保持するタイプです。タイプセーフ関数ポインタとも呼ばれます。デリゲートは、メソッドシグネチャを定義する型と言えます。
デリゲートをインスタンス化するとき、そのインスタンスを互換性のあるシグネチャを持つ任意のメソッドに関連付けることができます。デリゲートインスタンスを介してメソッドを呼び出す(または呼び出す)ことができます。デリゲートは、メソッドを引数として他のメソッドに渡すために使用されます。イベントハンドラーは、デリゲートを通じて呼び出されるメソッドにすぎません。デリゲートを使用する利点は、呼び出し元からのメソッドの呼び出しをカプセル化することです。デリゲートを効果的に使用すると、アプリケーションのパフォーマンスが向上します。デリゲートにはいくつかのプロパティがあります
Delegates are like C++ function pointers but are type safe.
Delegates allow methods to be passed as parameters.
Delegates can be used to define callback methods.
Delegates can be chained together; for example, multiple methods can be called on a single event.
Methods do not have to match the delegate signature exactly.
public delegate type_of_delegate delegate_name()//宣言
You can use delegates without parameters or with parameter list
If you are referring to the method with some data type then the delegate which you are declaring should be in the same format. This is why it is referred to as type safe function pointer. Here I am giving an example with String.
次の例は、デリゲート操作を示しています。
namespace MyDelegate
{
class Program
{
private delegate void Show(string s);
// Create a method for a delegate.
public static void MyDelegateMethod(string me
ssage)
{
System.Console.WriteLine(message);
}
static void Main(string[] args)
{
Show p = MyDelegateMethod;
p("My Delegate");
p.Invoke("My Delegate");
System.Console.ReadLine();
}
}
}
マルチキャストデリゲートとは何ですか?
複数のメソッドの参照を保持するデリゲートです。マルチキャストデリゲートには、voidを返すメソッドのみを含める必要があります。それ以外の場合は、実行時例外があります。
delegate void MyMulticastDelegate(int i, string s);
Class Class2
{
static void MyFirstDelegateMethod(int i, string s)
{
Console.WriteLine("My First Method");
}
static void MySecondDelegateMethod(int i, string s)
{
Console.WriteLine("My Second Method");
}
static void Main(string[] args)
{
MyMulticastDelegate Method= new MyMulticastDelegate(MyFirstDelegateMethod);
Method+= new MyMulticastDelegate (MySecondDelegateMethod);
Method(1,"Hi"); // Calling 2 Methodscalled
Method-= new MyMulticastDelegate (MyFirstDelegateMethod);
Method(2,"Hi"); //Only 2nd Method calling
}
}
ここでは、デリゲートは+ =演算子を使用して追加され、-=演算子を使用して削除されます。
デリゲート型は、.NET FrameworkのDelegateクラスから派生します。デリゲートタイプはシールされています。派生させることはできません。インスタンス化されたデリゲートはオブジェクトであるため、パラメーターとして渡すか、プロパティに割り当てることができます。これにより、メソッドはデリゲートをパラメーターとして受け入れ、後でデリゲートを呼び出すことができます。これは非同期コールバックと呼ばれます。
イベント通信では、送信者はどのオブジェクトがイベントを処理するかを認識していません。デリゲートはメソッドの参照を保持する型です。デリゲートにはシグネチャがあり、そのシグネチャに一致するメソッドへの参照を保持しているため、デリゲートはタイプセーフな関数ポインターのようなものです。
button1.Click + = new System.EventHandler(button1_Click)System.EventHandlerは、ここではデリゲートとして宣言されています。
デリゲートは、実行時に呼び出すコードがわからない場合に使用されるので、そのときにデリゲートを使用してイベントを処理します。
http://msdn.microsoft.com/en-us/library/ms173171(v=vs.80).aspx
デリゲートオブジェクトは、 何かが、そのオブジェクトに発生したときに別のオブジェクトを調べているオブジェクトです。たとえば、何かがあなたの車に起こった場合、あなたの修理人はあなたの代理人です。あなたはあなたの修理人のところへ行き、あなたに車を修理するように彼に頼みます(一部の人は自分で車を修理することを好むが、その場合、彼らは彼らの車のための彼ら自身の代理人です)。
デリゲートは、関数へのポインタを表すオブジェクトです。ただし、次の点で通常の関数ポインタではありません。
1)オブジェクト指向ですか
2)タイプセーフである、つまり、メソッドを指すことができるだけであり、メソッドが指す生のメモリアドレスを読み取ることができない
3)強く型付けされている。シグネチャに一致するメソッドのみを指すことができます。
4)同時に複数のメソッドを指すことができます。
デリゲートは主にイベントで使用されます。
必要性は:
プログラムを実行するときにコードを実行したくない。プログラムを実行した後、イベントが発生するたびにそのコードを実行します。
例:
これは彼らが言うことです、あなたはコンパイル時にどのメソッドが呼び出されるかわかりません。あなたはそれがボタンをクリックしたときである実行時にのみそれを知っています。
デリゲートがないと、ユーザーインターフェイスプログラミングはできません。ボタンをクリックしたり、テキストボックスに入力したり、ドロップダウンリストのアイテムを選択したりするなどのイベントをユーザーが行うたびにコードを実行しているためです。
デリゲートは、タスクが委任される対象です。委任の主な目的は、コードを分離し、柔軟性と再利用性を高めることです。
プログラミング、特にオブジェクト指向プログラミングでは、これは、メソッドが何らかの処理を行うために呼び出されると、参照先の別のオブジェクトのメソッドにその処理を渡すことを意味します。オブジェクトが事前定義されたメソッドのセットに準拠している限り、参照は任意のオブジェクトを指すことができます。これを「インターフェイスへのプログラミング」と呼びます(具体的なクラス実装へのプログラミングではありません)。インターフェイスは基本的に汎用テンプレートであり、実装はありません。それは単にレシピ、メソッドのセット、前提条件と事後条件(ルール)を意味します。
簡単な例:
SomeInterface
{
public void doSomething();
}
SomeImplementation implements SomeInterface
{
public void doSomething()
{
System.err.println("Was it good for you?");
}
}
SomeCaller
{
public void doIt(SomeInterface someInterface)
{
someInterface.doSomething();
}
}
これで、SomeCallerのコードを変更せずに、いつでも好きな実装を使用できることがわかりdoIt()
ます。これは、渡される型が具体的ではなく、インターフェースであるため抽象的だからです。Javaの世界では、これは多くの場合、サービス(特定のインターフェースを介してそれ自体をサービスとしてアドバタイズするオブジェクト)を呼び出し、次にサービスがデリゲートに呼び出しを行うサービスパラダイムで表されます。サービスのメソッドは、粒度の粗いタスク(makePayment()、createNewUser()など)として名前が付けられていますが、デリゲートの型が具体的な実装ではなくインターフェイスであるデリゲートの種類によって、デリケートな機能が内部的に機能する場合、内部的には多くのことが行われます。
SomeService
{
SomeInterface someImplementation = ... // assign here
SomeOtherInterface someOtherImplementation = ... // okay, let's add a second
public void doSomeWork()
{
someImplementation.doSomething();
someOtherImplementation.doSomethingElse();
}
}
(注:実装がどのように割り当てられるかは、このスレッドの範囲を超えています。制御の逆参照と依存性注入。)
デリゲートは実際には「関数ポインタ」ではありませんが、PHPのような動的言語のように見える場合があります。
$func = 'foo';
$func();
function foo() {
print 'foo';
}
またはJavaScriptであなたは次のようなことをすることができます:
var func = function(){ alert('foo!'); }
func();