C# デリゲート、匿名メソッド、ラムダ式、ジェネリックデリゲート、式木のコード例

C# デリゲート、匿名メソッド、ラムダ式、ジェネリックデリゲート、式木のコード例

教科書やブログではデリゲートについて述べるとき、必ずイベントに触れますが、イベントはデリゲートのインスタンスに過ぎません。理解を簡単にするため、今日はデリゲートだけを扱い、イベントは扱いません。

最終更新 2021/09/18 11:39
QueryWord
読了目安 3 分
カテゴリ
.NET
タグ
.NET C# 式木 ジェネリックデリゲート 匿名メソッド

第1分:デリゲート

一部の教材やブログでは、デリゲートについて触れると必ずイベントが登場します。イベントはデリゲートのインスタンスですが、理解を簡単にするため、今日はデリゲートだけを扱い、イベントは扱いません。まずは次のコードをご覧ください。

以下のコードは、デリゲートアプリケーションのデモを完成させています。デリゲートは3つのステップで構成されます。

class Program
{
    // step01:まず delegate を使用してデリゲートを定義する。
    public delegate int CalculatorAdd(int x, int y);

    static void Main(string[] args)
    {
        // step03:このメソッドを使用してデリゲートをインスタンス化する。
        CalculatorAdd cAdd = new CalculatorAdd(Add);

        // int result = cAdd(5, 6);
        int result = cAdd.Invoke(5, 6);
    }

    // step02:デリゲートに対応するメソッドを宣言する。
    public static int Add(int x, int y)
    {
        return x + y;
    }
}
  • step01:まず delegate を使用してデリゲートを定義する。
  • step02:デリゲートに対応するメソッドを宣言する。
  • step03:このメソッドを使用してデリゲートをインスタンス化する。

これでデリゲートアプリケーションが完成し、デリゲートを呼び出すことができます。

第2分:匿名メソッド

前の分で、デリゲートアプリケーションを完成させるには3ステップが必要で、1つでも欠けてはいけないことがわかりました。大きなステップを踏もうとすると、リスクが伴います。しかしマイクロソフトはそのリスクを恐れず、3ステップを2ステップにしようとしました。そこで匿名メソッドを使用して上記の3ステップを簡略化しました。匿名メソッドは、C#では必須のものではなく、C#をさらに便利にするための、いわゆる「シンタックスシュガー」です。

class Program
{
    // step01:まず delegate を使用してデリゲートを定義する。
    public delegate int CalculatorAdd(int x, int y);

    static void Main(string[] args)
    {
        // step02:delegate(int x, int y) { return x + y; } のように記述して、メソッドをデリゲートに割り当てる
        CalculatorAdd cAdd = delegate (int x, int y) { return x + y; };

        int result = cAdd.Invoke(5, 6);
    }
}
  • step01:まず delegate を使用してデリゲートを定義する。
  • step02:delegate(int x, int y) { return x + y; } のように記述して、メソッドをデリゲートに割り当てる。この記述が匿名メソッドである。

これで、3ステップが2ステップに減ったことに驚くでしょう。

第3分:ラムダ式

本来単純なプログラムにいくつかの delegate キーワードを追加すると、コードが急に難解になり、理解する人が減ります。そのため、これを給与交渉の材料にすることもできます。しかし、マイクロソフトの設計哲学はシンプルで使いやすいことです。そこでマイクロソフトは delegate(int x, int y) { return x + y; } という匿名メソッドをさらに簡略化しようと試み、ラムダ式が登場しました。以下に、いくつかのラムダ式の書き方を示します。

class Program
{
    public delegate int CalculatorAdd(int x, int y);
    static void Main(string[] args)
    {
        // 方法1:
        CalculatorAdd cAdd1 = (int x, int y) => { return x + y; };
        int result1 = cAdd1(5, 6);

        // 方法2:
        CalculatorAdd cAdd2 = (x, y) => { return x + y; };
        int result2 = cAdd2(5, 6);

        // 方法3:
        CalculatorAdd cAdd3 = (x, y) => x + y;
        int result3 = cAdd2(5, 6);
    }
}

第4分:ジェネリックデリゲート

.NET のバージョンが上がるにつれて、新しいバージョンは旧バージョンと差別化する必要があります。さもなければ、マイクロソフトのエンジニアが上司に説明できません。そこでマイクロソフトはまた新たな機能を導入しました。

class Program
{
    static void Main(string[] args)
    {
        // 方法1:
        Func<int, int, int> cAdd1 = (int x, int y) => { return x + y; };
        int result1 = cAdd1(5, 6);

        // 方法2:
        Func<int, int, int> cAdd2 = (x, y) => { return x + y; };
        int result2 = cAdd2(5, 6);

        // 方法3:
        Func<int, int, int> cAdd3 = (x, y) => x + y;
        int result3 = cAdd2(5, 6);
    }
}

匿名メソッドでもラムダ式でも、デリゲートアプリケーションを完成させるには、デリゲートを定義するステップと、メソッドを使用してデリゲートをインスタンス化するステップの2つを避けられません。マイクロソフトはこれら2つのステップを1つに統合しました。Func を使用してデリゲートの定義を簡略化します。

これで、デリゲートアプリケーションは Func<int, int, int> cAdd3 = (x, y) => x + y; という1行で完了します。この Func がいわゆるジェネリックデリゲートです。

第5分:式木

式木は実際にはデリゲートとはあまり関係がありません。無理やり関係づけるなら、式木はデリゲートを格納するコンテナです。より専門的に言えば、式木はラムダ式を格納するためのデータ構造です。ラムダ式が必要なときは、式から取り出して Compile() を呼び出すだけで使用できます。次のコードを参照してください。

class Program
{
    static void Main(string[] args)
    {
        Expression<Func<int, int, int>> exp = (x, y) => x + y;
        Func<int, int, int> fun = exp.Compile();
        int result = fun(2, 3);
    }
}
さらに探索

関連読書

その他の記事
同じカテゴリ / 同じタグ 2026/04/22

各OSバージョンの.NETサポート状況(250707更新)

仮想マシンとテストマシンを使用して、各OSバージョンの.NETサポート状況を確認します。OSインストール後、対応するランタイムをインストールし、Stardustエージェントを実行できることを確認します(合格条件)。

続きを読む
同じカテゴリ / 同じタグ 2026/02/07

AOTの使用経験のまとめ

プロジェクト作成当初から、新機能を追加したり新しい構文を使用したりした場合には、すぐにAOT公開テストを実施するという良い習慣を身につけるべきです。

続きを読む