C#のデリゲートについて(書き方の変遷など)


デリゲートについて

  • 現在ではほぼしない、古典的な書き方(デリゲートの型を自分で宣言する)
public class ClassSample
{
    delegate int Delegate_A(string s); // Delegate_A という名前の「型」を定義

    static void Main()
    {
        // デリゲートはひとつの「型」なので、他のクラスを使用するときと同じ書き方でインスタンス化できる
        Delegate_A dlg = new Delegate_A(work);    // C#1.0
        //Delegate_A dlg = work;                // C#2.0 で new なしで書けるようになった

        // 作成したインスタンスに引数を渡しつつ呼び出す
        int result = dlg("123");
    }

    // デリゲートから呼び出されるメソッド
    private static int work(string s)
    {
        return int.Parse(s);
    }
}
  • .NET Framework 3.5以降では、定義済デリゲートにより、独自のデリゲート定義が不要になりました。
    戻り値を持たない Action<T>型 と、戻り値を持つ Func<T,TResult>型 などが使えます。
    上記のコードを定義済デリゲートと使って書き換えると下記のようになります。
public class ClassSample
{
    // 独自デリゲート型の宣言が不要になった

    static void Main()
    {
        // 定義済デリゲートのインスタンスを生成(newを省略した書き方)
        Func<string,int> dlg = work;

        // 作成したインスタンスに引数を渡しつつ呼び出す
        int result = dlg("123");
    }

    // デリゲートから呼び出されるメソッド
    private static int work(string s)
    {
        return int.Parse(s);
    }
}
  • また、ラムダ式を使うことより、別メソッドに記述していた処理内容をその場で書けるようになりました。
public class ClassSample
{
    static void Main()
    {
        // メソッドの内容を (引数) => {処理(式)} で書ける
        //Func<string,int> dlg = (string s) => { return int.Parse(s); };

        // 引数の型(string)は型推論により省略可能
        // 処理部分がreturn のみの場合は{}も省略可能
        Func<string,int> dlg = s => int.Parse(s);

        // 作成したインスタンスに引数を渡しつつ呼び出す
        int result = dlg("123");
    }
}