デリゲート
デリゲート
Delegateは委譲という意味で、委譲する内容は処理(メソッド)。
定義方法は、処理を記述しない以外は、通常のメソッドと同様で、それにdelegateキーワードを指定する。
デリゲート型の変数には、戻り値と引数リストが一致するメソッドを代入できる(派生クラス(ダウンキャスト)は可能)
delegate 戻り値 デリゲート名(引数リスト);
代入するメソッドについて
つまり、代入するメソッドの使用回数によらず、どこかに
C#では、これを簡単にするために、以下の"匿名関数"と"ラムダ式"が存在する。
匿名関数
delegate (引数リスト){処理}
ラムダ式
前述の匿名関数と異なりデリゲート以外の用途がある。
一般的な定義は以下の①であるが、引数が明確な場合には②のように省略することができる。
(int n) => n > 0; // ①
n => n > 0; // ② 0と比較しているため、引数がint型であることは明確
マルチキャスト
複数のメソッドが代入されているデリゲートを呼び出すと、代入順に逐次実行される。
戻り値が存在する場合は、最後の戻り値のみ取得できない。
述語
Action
定義は以下の通り。
public delegate void Action<in T> (T obj);
Func
定義は以下の通り。
public delegate TResult Func<in T,out TResult> (T obj);
まとめ
delegate・Action
class Action101
{
private delegate void DisplayDelegate(string str);
// デリゲートを使用して2回文字列を表示する。
internal static void DeisplayByDelegate(string[] strs)
{
var displayDelegate = new DisplayDelegate((string str) => Console.WriteLine("First Delegate: " + str));
displayDelegate += (string str) => Console.WriteLine("Second Delegate: " + str);
ExecDeisplayByDelegate(strs, displayDelegate);
}
// Actionを使用して2回文字列を表示する。
internal static void DisplayByAction(string[] strs)
{
var displayAction = new Action<string>((string str) => Console.WriteLine("First Action: " + str));
displayAction += (string str) => Console.WriteLine("Second Action: " + str);
ExecDisplayByAction(strs, displayAction);
}
private static void ExecDeisplayByDelegate(string[] strs, DisplayDelegate displayDelegate)
{
foreach (var str in strs)
displayDelegate(str); // 戻り値が存在しないのでOK
}
private static void ExecDisplayByAction(string[] strs, Action displayAction)
{
foreach (var str in strs)
displayAction(str); // 戻り値が存在しないのでOK
}
}
delegate・Func
internal class Func101
{
private delegate bool Condition(int n);
internal static void DisplayGreaterThan5EvenNumberByDelegate(int[] nums)
{
var condition = new Condition(n => n >= 5);
condition += n => n % 2 == 0;
ExecDisplayGreaterThan5EvenNumberByDelegate(nums, condition);
}
internal static void DisplayGreaterThan5EvenNumberByFunc(int[] nums)
{
var condition = new Func<int, bool>(n => n >= 5);
condition += n => n % 2 == 0;
ExecDisplayGreaterThan5EvenNumberByFunc(nums, condition);
}
private static void ExecDisplayGreaterThan5EvenNumberByDelegate(int[] nums, Condition condition)
{
foreach (var num in nums)
{
var result = true;
foreach (Condition cond in condition.GetInvocationList())
result &= cond(num);
if (!result) continue;
Console.WriteLine("Delegate: " + num);
}
}
private static void ExecDisplayGreaterThan5EvenNumberByFunc(int[] nums, Func<int, bool> condition)
{
foreach (var num in nums)
{
var result = true;
foreach (Func<int, bool> cond in condition.GetInvocationList())
result &= cond(num);
if (!result) continue;
Console.WriteLine("Delegate: " + num);
}
}
}