class Test {
static void Main() {
// Delegator を作成して, void、パラメータ無しのメソッドの位置を保有する。
TestCallback test = new TestCallback(Test);
// callback を呼ぶ。
test();
}
static void Test() {
System.Console.WriteLine("Test on your lap");
}
}
delegateとは何か
POINT
関数ポインターのこと。
委譲という言葉が分かりにくいと思うなら、「代表者」と考えてもよい。
何かの処理を実行させたいときに、直接処理機能を持つメソッドを呼び出すのではなく、
代表者に処理を求めるのである。代表者は処理機能自体は持っていないが、
それを処理できる適切なメソッドを知っていてそのメソッドに処理要求を渡す。
EventHandler pFoo; といいかえれば OK.
「 クラスA 」の「 メソッドa 」は自分では何も処理せず、
常に「 クラスB 」の「 メソッドb 」に処理をゆだねるとしよう。
このような場合、「 メソッドa 」の中に「 メソッドb 」を呼び出すコードを書けばよいので、
特別な機能は何も必要がない。
A::methodA() {
// ここを固定したくない
B::methodB();
}
POINT
このように常に処理をゆだねる相手が決まっているとは限らないし、
相手が常に1つとも限らない
この状況に対応するために delegate を使う。
WARNING
delegateの機能はeventの機能によく似ている
実際に、event機能はdelegate機能を利用して作られている。
delegateとeventは想定される使われ方が違っており
機能面でも違いがある。
delegateは処理を他にゆだねるものだが
eventはクラス内の出来事を外部に伝えるもの。
どちらか一方だけ覚えて
他方は使わないという方法はうまくいかない。
関数ポインタと似ているのは役割であって
関数ポインタの機能とdelegateの機能が同じではない。
C言語で関数ポインタを使っていた場面で、
C#ではdelegateを使うかもしれないが
具体的な機能はまったく違うということ
// delegate経由でメソッドを呼び出すサンプル
using System;
namespace ConsoleApplication20
{
// delegate 型だよ - ^ ^/
// Signature は int ( int, int ); だよ. ^ ^/
// そして 名前は Sample だよ. ^ ^/
// delegate のデータ型を決める。
// 呼び出せるのは、あくまで同じ戻り値、同じ引数のメソッドのため型を決めておく。
// データ型の名前となる。
// delegate の宣言には、public や private などのキーワードも付けることもできる。
delegate int Sample( int x, int y );
class Class2
{
// Signature が同じであることが POINT
public int method( int x, int y )
{
return x*y;
}
}
class Class1
{
static void Main(string[] args)
{
Class2 instance = new Class2();
// 代理人を作成する際に, Method をもらう. ( Isntance つき. )
// delegate を作成して instance のメソッドを渡す。
Sample sample = new Sample( instance.method );
// 代理人経由で呼び出す.
int result = sample( 2, 3 );
Console.WriteLine( result );
}
}
}
POINT
delegate を使って異なる処理が一元化できる。
using System;
namespace ConsoleApplication21
{
delegate int Sample( int x, int y );
class Class2
{
public int methodMult( int x, int y )
{
return x*y;
}
public int methodPlus( int x, int y )
{
return x+y;
}
}
class Class1
{
// delegate 型を外からもらうことが可能.
// 計算方法を外へ出すということ。
public static void calc( int x, int y, Sample calcMethod )
{
// calcメソッドで、さまざまな計算を実行させたい
// このdelegateのインスタンスの移譲先として指定するメソッドを入れ替えれば
計算内容も変わる
int result = calcMethod( x, y );
Console.WriteLine( result );
}
static void Main(string[] args)
{
Class2 instance = new Class2();
calc( 2, 3, new Sample( instance.methodMult ) );
calc( 2, 3, new Sample( instance.methodPlus ) );
}
}
}