デリゲートには次の特性があります。
- デリゲートは C/C++ の関数ポインターに似ていますが、完全にオブジェクト指向です。さらに、C++ のポインターは関数を記憶しますが、デリゲートはオブジェクト インスタンスとメソッドを同時にカプセル化します。
- デリゲートを使用すると、メソッドをパラメータとして渡すことができます。
- デリゲートを使用してコールバック メソッドを定義できます。
- デリゲートは連鎖させることができます。たとえば、イベントに対して複数のメソッドを呼び出すことができます。
- メソッドはデリゲートの型と正確に一致する必要はありません。
- C# バージョン 2.0 では、匿名関数の概念が導入されました。これにより、コードのブロックを、個別に定義されたメソッドの代わりにパラメーターとして渡すことができます。 C# 3.0 ではラムダ式が導入され、インライン コード ブロックをより簡潔に記述できるようになりました。匿名メソッドとラムダ式は両方ともデリゲート型にコンパイルされ、これらの機能は総称して匿名関数と呼ばれるようになりました。
委任を宣言する
デリゲートを宣言するには、delegate キーワードを使用する必要があります。構文は次のとおりです。
delegate <return type> delegate-name(<parameter list>)
このうち、return type は戻り値の型、delegate-name はデリゲートの名前、parameter list はパラメータのリストです。
ヒント: デリゲートは、デリゲートと同じシグネチャを持つメソッドを参照できます。つまり、デリゲートが参照できるメソッドは、デリゲートが宣言されたときに決定されます。
デリゲートをインスタンス化する
デリゲートを宣言した後、それを使用する場合は、 new キーワードを使用してデリゲートされたオブジェクトを作成し、それを特定のメソッドに関連付ける必要があります。次の例に示すように:
public delegate void printString(string s);
…
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
[例] 以下は、デリゲートの宣言、インスタンス化、および使用方法を示す具体的な例です. デリゲートを使用すると、整数パラメータを持つメソッドを参照し、整数値を返すことができます。
using System;
delegate int NumberChanger(int n); // 委任を定義する
namespace it-kiso.com
{
class Demo
{
static int num = 10;
public static int AddNum(int p)
{
num += p;
return num;
}
public static int MultNum(int q)
{
num *= q;
return num;
}
public static int getNum()
{
return num;
}
static void Main(string[] args)
{
// 委任インスタンスを作る
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
// 委任オブジェクトを使ってメソッドを呼び出す
nc1(25);
Console.WriteLine("numの値は{0}", getNum());
nc2(5);
Console.WriteLine("numの値は{0}", getNum());
Console.ReadKey();
}
}
}
操作の結果は次のようになります。
numの値は
35
numの値は
175
デリゲート オブジェクトには非常に便利なプロパティがあり、 +
演算子を使用して複数のオブジェクトをデリゲート インスタンスに割り当てることができ、同時に、 -
演算子を使用して割り当てられたオブジェクトをデリゲートから削除できます。が呼び出されると、リスト内のデリゲートを順番に呼び出します。デリゲートのこのプロパティは、デリゲートのマルチキャストとして知られており、マルチキャストとも呼ばれます。デリゲートのこのプロパティを使用すると、デリゲートが呼び出されたときに呼び出されるメソッドのリストを作成できます。
注: 同じ種類の注文のみを結合できます。
以下は、サンプル プログラムを使用して委任されたマルチキャストを示しています。
using System;
delegate int NumberChanger(int n); // デリゲートの定義
namespace it-kiso.com
{
class Demo
{
static int num = 10;
public static int AddNum(int p){
num += p;
return num;
}
public static int MultNum(int q){
num *= q;
return num;
}
public static int getNum(){
return num;
}
static void Main(string[] args){
// デリゲートのインスタンスを作成
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
// マルチキャストを呼び出す
nc(5);
Console.WriteLine("num の値は: {0}", getNum());
Console.ReadKey();
}
}
}
操作の結果は次のようになります。
num の値は:
75
[例] 以下はデリゲート printString を定義します。このデリゲートを使用して 2 つのメソッドを呼び出します。1 つ目は文字列をコンソールに出力し、2 つ目は文字列をファイルに出力します。
using System;
using System.IO;
namespace it-kiso.com
{
class Demo
{
static FileStream fs;
static StreamWriter sw;
// delegate宣言
public delegate void printString(string s);
// このメソッドはコンソールに出力します。
public static void WriteToScreen(string str){
Console.WriteLine("The String is: {0}", str);
}
// このメソッドはファイルに出力します。
public static void WriteToFile(string s){
fs = new FileStream("./message.txt", FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
sw.WriteLine(s);
sw.Flush();
sw.Close();
fs.Close();
}
// このメソッドはdelegateをパラメーターとして受け取り、そのdelegateを使用してメソッドを呼び出します。
public static void sendString(printString ps)
{
ps("IT基礎");
}
static void Main(string[] args){
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
sendString(ps1);
sendString(ps2);
Console.ReadKey();
}
}
}
上記のコードを実行すると、プログラムが配置されているディレクトリに message.txt という名前のファイルが生成され、次の内容が出力されます。
The String is: IT基礎