C# デリゲート完全ガイド:関数参照とイベントの仕組みを理解する
C# のデリゲートは、C や C++ の関数ポインタに似ています。デリゲートはメソッドへの参照を保持する参照型の変数であり、その参照は実行時に変更可能です。
デリゲートは特にイベントやコールバック メソッドの実装に使用されます。すべてのデリゲートは暗黙的に System.Delegate クラスから派生します。
デリゲートの宣言
デリゲートの宣言によって、そのデリゲートが参照できるメソッドのシグネチャが決まります。デリゲートは、自分と同じシグネチャを持つメソッドを参照できます。
たとえば、次のようなデリゲートを考えます。
public delegate int MyDelegate(string s);
このデリゲートは、string 型のパラメータを 1 つ取り、int 型の値を返すあらゆるメソッドを参照するために使用できます。
デリゲート宣言の構文は次のとおりです。
delegate <戻り値の型> <デリゲート名> <パラメータ リスト>
デリゲートのインスタンス化
デリゲート型を宣言したら、new キーワードを使ってデリゲート オブジェクトを作成し、特定のメソッドと関連付けます。デリゲートを作成するとき、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 DelegateAppl {
class TestDelegate {
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("Value of Num: {0}", getNum());
nc2(5);
Console.WriteLine("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
Value of Num: 35 Value of Num: 175
デリゲートのマルチキャスト
デリゲート オブジェクトは「+」演算子を使って合成できます。合成されたデリゲートは、元になった 2 つのデリゲートを順に呼び出します。同じ型のデリゲート同士のみ合成可能です。「-」演算子を使えば、合成されたデリゲートから特定のデリゲートを削除できます。
この性質を利用すると、デリゲートが呼び出されたときに実行されるメソッドの呼び出しリスト(マルチキャスト)を作成できます。次のプログラムはデリゲートのマルチキャストを示しています。
ライブ デモusing System;
delegate int NumberChanger(int n);
namespace DelegateAppl {
class TestDelegate {
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("Value of Num: {0}", getNum());
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
Value of Num: 75
デリゲートの活用
次の例はデリゲートの実用的な使い方を示しています。デリゲート printString は、文字列を受け取って何も返さないメソッドを参照するために使用できます。
このデリゲートを使って 2 つのメソッドを呼び出します。1 つ目は文字列をコンソールに出力し、2 つ目はファイルに出力します。
ライブ デモusing System;
using System.IO;
namespace DelegateAppl {
class PrintString {
static FileStream fs;
static StreamWriter sw;
// デリゲート宣言
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("c:\\message.txt", FileMode.Append, FileAccess.Write);
sw = new StreamWriter(fs);
sw.WriteLine(s);
sw.Flush();
sw.Close();
fs.Close();
}
// デリゲートをパラメータとして受け取り、必要に応じてメソッドを呼び出す
public static void sendString(printString ps) {
ps("Hello World");
}
static void Main(string[] args) {
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
sendString(ps1);
sendString(ps2);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が得られます。
The String is: Hello World
C言語
- エコノミスト・イノベーション・サミットでAIが主役に——リーダーたちは「人間の代替」でなく「人間の拡張」を訴える
- C# Hello World – 初めてのC#アプリケーション構築
- C# キーワードと識別子:ルール、一覧、ベストプラクティス完全ガイド
- C# 変数とプリミティブデータ型:完全マスターガイド
- C#演算子完全ガイド:C#における演算子の包括的解説
- C言語ユーザー定義関数の4つの実証済みパターン
- C言語で1次元・2次元配列を関数に渡す方法 – 実践ガイド
- C++変数とデータ型:int、double、char、string、boolを徹底解説
- C言語の関数マスター:構造、宣言、ベストプラクティス
- C言語ビットフィールド:メモリ効率を最大化するテクニック
- C言語可変長引数のマスター:実践ガイド