デリゲート

デリゲート

メソッドへの参照を表す型(デリゲート型)
Delegateは委譲という意味で、委譲する内容は処理
定義方法は、処理を記述しない以外は、通常のメソッドと同様で、それにdelegateキーワードを指定する。
デリゲート型の変数には、戻り値と引数リストが一致するメソッドを代入できる(派生クラス(ダウンキャスト)は可能)
delegate 戻り値 デリゲート名(引数リスト);

マルチキャスト

+,-演算子で複数のメソッドを代入することができる。
複数のメソッドが代入されているデリゲートを呼び出すと、代入順に逐次実行される。

述語

デリゲートの主要な用途の1つで、条件を満たすかどうかを調べるメソッド(述語)を代入し、ほかのメソッドに渡す方法がある。

代入するメソッドについて

デリゲート型の変数に代入するメソッドは、クラス(static)メソッド、インスタンスメソッドのどちらでも代入することができる。
つまり、代入するメソッドの使用回数によらず、どこかに必ず1回は定義しなければならない。
C#では、これを簡単にする仕組みが存在する。
匿名関数
デリゲート用の仕組みで、後述するラムダ式はさらに簡素化されて、機能も充実している。(デリゲート以外の用途がある)
delegate (引数リスト){処理}
ラムダ式
関数を整数などの変数と同じように扱う。
一般的な定義は以下の①であるが、引数が明確な場合には②のように省略することができる。
(int n) => n > 0; // ①
n => n > 0; // ② 0と比較しているため、引数がint型であることは明確

まとめ

デリゲートの基礎をまとめるために、以下のプログラムを考える。
配列内の、5以上の偶数を表示する
internal class Summary
{
    private delegate bool DGCondition(int n);

    internal static void DispGT5Even(int[] nums)
    {
        DGCondition prediction = n => n >= 5;
        prediction += n => n % 2 == 0;
        GetGT5Even(nums, prediction);
    }

    private static void GetGT5Even(int[] nums, DGCondition prediction)
    {
        foreach (var num in nums)
        {
            var condition = prediction(num);
            condition &= prediction(num);
            if (!condition) continue;
            System.Console.WriteLine(num);
        }
    }
}