デリゲートとは
デリゲートはC#において関数やメソッドを変数として扱うための仕組みです。概念的にはC++の関数ポインタに似ていますが、より強力で安全な設計が可能です。
以下はC++の関数ポインタの例です:
int max(int a, int b) {
return a > b ? a : b;
}
int (*pf)(int, int);
pf = max;
int result = pf(1, 5);
関数ポインタとデリゲートの違い
- 型安全性: C#のデリゲートはコンパイル時に型チェックが行われるため、不適切なメソッドの代入はエラーになります。
- ガベージコレクション: デリゲートは自動的にメモリ管理されるため、リークのリスクが低減されます。
- インスタンスメソッドの参照: デリゲートはオブジェクトインスタンスとメソッドを一緒に保持できます。
- マルチキャスト: 複数のメソッドを1つのデリゲートに登録して、一括実行できます。
- Lambda式との統合: 無名関数を簡潔に記述できます。
デリゲートの基本的な使い方
1. デリゲートの宣言
// クラス外で宣言
public delegate void Notification(string message);
public class SampleClass {
// クラス内で宣言
public delegate int Calculation(int x, int y);
}
2. デリゲートのインスタンス化
Notification notifier = MessageHandler.ShowMessage;
3. デリゲートの呼び出し
notifier("アプリケーション通知");
Lambda式によるデリゲートの初期化
{
// 引数あり戻り値なし
Notification logWriter = (msg) => {
Console.WriteLine($"ログ: {msg}");
};
logWriter("テストメッセージ");
}
{
// 引数・戻り値あり
SampleClass.Calculation calc = (a, b) => {
return a + b;
};
int sum = calc(3, 4);
Console.WriteLine(sum);
}
マルチキャストデリゲート
Notification alert = MessageHandler.ShowMessage;
alert += MessageHandler.LogMessage;
alert("重要な通知");
コールバックの実装
public static void ExecuteWithCallback(int val1, int val2, Notification callback) {
int result = val1 + val2;
callback($"結果は {result} です");
}
サンプル実装
メソッドクラス
public class MessageHandler {
public static void ShowMessage(string msg) {
Console.WriteLine($"通知: {msg}");
}
public static void LogMessage(string msg) {
Console.WriteLine($"ログ記録: {msg}");
}
public static int AddValues(int a, int b) {
return a + b;
}
}
メイン処理
{
// クラス内デリゲートの使用
var sample = new SampleClass();
SampleClass.Calculation calc = MessageHandler.AddValues;
int total = calc(10, 20);
Console.WriteLine(total);
}
{
// コールバックの使用
Notification callback = MessageHandler.ShowMessage;
MessageHandler.ExecuteWithCallback(5, 8, callback);
}
{
// マルチキャストデリゲート
Notification alert = MessageHandler.ShowMessage;
alert += MessageHandler.LogMessage;
alert("システムアラート");
}