tl;dr(まとめ)
C#のデリゲートは、 引数として関数を1つ受けとるデータ型(参照型) の一種です。
C#には他にもnewキーワードで生成するデータ型としてクラス、構造体があります。
C#のデリゲートは、+
, -
演算子を持ち、一つのデリゲート変数に複数のデリゲートを登録することが出来、 マルチキャスト と呼ばれる機能を持ちます。
(これが、C#のデリゲートの特筆すべき機能だと思います。)
書いたこと
- デリゲートの宣言
- デリゲートの生成と実行
3. newキーワドによる生成
4. 匿名メソッドによる生成
5. ラムダ式による生成 - デリゲートの+-演算 (マルチキャスト)
デリゲートの宣言
デリゲートの宣言
delegate 戻り値の型 デリゲート名 (関数が引き受ける仮引数);
例: 「2つのint型の引数を受け取りint型の値を返す関数」のデリゲート宣言
Calculateデリゲートの宣言
// Calculateデリゲートの宣言
delegate int Calculate (int a, int b);
- 仮引数名が要ることが残念ですね。
デリゲートの生成と実行
newキーワードによる生成
newキーワードによるデリゲートの生成
using System;
// デリゲートの宣言
delegate void Printer (string s);
class Test {
public static void Main() {
// デリゲートの生成
Printer print = new Printer(Console.WriteLine);
// デリゲートの実行
print("Hello World");
}
}
- 引数としてクラスメソッド、もしくはインスタンスメソッドを受け取る
匿名メソッドによる生成
匿名メソッドによるデリゲートの生成
using System;
// デリゲートの宣言
delegate void Printer (string s);
class Test {
public static void Main() {
// デリゲートの生成
Printer print = delegate (string s) {
Console.WriteLine(s);
};
// デリゲートの実行
print("Hello World");
// 匿名メソッドはデリゲート変数に代入することも可能
print = delegate (string s) {
Console.WriteLine($"You inputed \"{s}\"");
};
print("I'm fine");
}
}
/* 実行結果
Hello World
You inputed "I'm fine"
*/
- delegateキーワードを使うことで匿名メソッドを定義することが出来る
- 匿名メソッドはデリゲートの初期化もしくはデリゲート変数に代入する事ができる。
- つまり匿名メソッドはデリゲートを生成する
ラムダ式による生成
ラムダ式によるデリゲートの生成
using System;
// デリゲートの宣言
delegate void Printer (string s);
class Test {
public static void Main() {
Printer print = (string s) => {
Console.WriteLine($"You inputed \"{s}\"");
};
print("I'm fine");
}
}
- ラムダ式も匿名メソッドと同じ様に、デリゲート変数の初期化、もしくは代入を行うことが出来る。
- つまりラムダ式もデリゲートを生成する
デリゲートの+-演算 (マルチキャスト)
C#のデリゲートは一つのデリゲート変数に複数のデリゲートを登録することが出来ます。
( マルチキャスト機能 と呼ばれます。)
マルチキャストによる複数のデリゲートの登録
using System;
// デリゲートの宣言
delegate void Calculator (int other);
class Test {
public static void Main() {
var i = new Integer(5);
// 一つのデリゲート変数に複数のデリゲートを登録できる
var calculator = new Calculator(i.Add) + new Calculator(i.Sub) + new Calculator(i.Mul);
// デリゲートを実行
calculator(5);
Console.WriteLine("-- 引き算を削除 --");
// 登録したデリゲートを削除することが出来る
calculator -= new Calculator(i.Sub);
// デリゲートを実行
calculator(10);
}
}
class Integer {
public int val;
public Integer(int n) {
val = n;
}
public void Add(int n) {
Console.WriteLine($"足し算の結果は: {val + n}です。");
}
public void Sub(int n) {
Console.WriteLine($"引き算の結果は: {val - n}です。");
}
public void Mul(int n) {
Console.WriteLine($"掛け算の結果は: {val * n}です。");
}
}
/* 実行結果
足し算の結果は: 10です。
引き算の結果は: 0です。
掛け算の結果は: 25です。
-- 引き算を削除 --
足し算の結果は: 15です。
掛け算の結果は: 50です。
*/
-
+
演算子を使って追加登録 -
-
演算子を使って登録から削除
Appendix
匿名メソッド
匿名メソッドの定義
delegate (仮引数) {
// 式
}
- 生成するデリゲートの型は、コンパイラが推論してくれる
ラムダ式
ラムダ式
(仮引数) => {
// 式
}
- 生成するデリゲートの型は、コンパイラが推論してくれる