デリゲートの歴史

2019年12月16日

C#のバージョンアップでデリゲートの構文が簡略化されてきました。

各バージョンでどのように更新されていったのかみていきましょう。

C#1.0

デリゲートを宣言、インスタンスを作成しコンストラクタでメソッドを設定します

// デリゲートの宣言
delegate void Del(string str);
class Program
{
    static void Main(string[] args)
    {
        // デリゲートインスタンスの作成
        Del del1 = new Del(Notify)
        // デリゲート呼び出し
        del1("メイン");
    }
    // デリゲートと同じシグネチャを持つメソッドを宣言します
    static void Notify(string name)
    {
        Console.WriteLine($"{name}からの通知の受信");
    }
}

C#2.0

デリゲートインスタンスの作成で、newを省略できるようになりました。
より簡単にDelのインスタンスを宣言する方法を提供します。

// デリゲートの宣言
delegate void Del(string str);
class Program
{
    static void Main(string[] args)
    {
        // デリゲートインスタンスの作成(newの省略)
        Del del2 = Notify;
        del2("メイン");
    }
    // デリゲートと同じシグネチャを持つメソッドを宣言します
    static void Notify(string name)
    {
        Console.WriteLine($"{name}からの通知の受信");
    }
}

C#2.0以降

匿名メソッドを使用してデリゲートの宣言と初期化を行うこともできるようになりました。
メソッドの利用場所が限られている場合、メソッド名Notifyを省略することができます。
これは、定義しているメソッドの中でした使えません。
デリゲート型変数にメソッドを直接代入してしまいます。

// デリゲートの宣言
delegate void Del(string str);
class Program
{
    static void Main(string[] args)
    {
        // 匿名メソッドを使用してDelをインスタンス化します。
        Del del3 = delegate (string name)
        {
            Console.WriteLine($"{name}からの通知の受信");
        };
      del3("メイン");
    }
}

C#3

ラムダ式を使用してデリゲートの宣言とインスタンス化を行うこともできるようになりました

// デリゲートの宣言
delegate void Del(string str);
class Program
{
    static void Main(string[] args)
    {
        // ラムダ式を使用してDelをインスタンス化します。
        Del del4 = name =>
        {
            Console.WriteLine($"{name}からの通知の受信");
        };
        del4("メイン");
    }
}

Action<> , Func<>デリゲートを使う


これにより、デリゲートの宣言も短く省略することができます。

これまでのデリゲートの宣言、代入
// デリゲートの宣言
// 戻り値がなく、string型引数を1つとるメソッド
delegate void Del(string str);
Del del;

は、まとめて次のように簡略化できます。(Action)

Action<string>デリゲートに置き換え
// 戻り値がなく、string型引数を1つとるメソッド
Action<string> del5;
class Program
{
    static void Main(string[] args)
    {
        // ラムダ式を使用してDelをインスタンス化します。
        Action<string> del5 = name =>
        {
            Console.WriteLine($"{name}からの通知の受信");
        };
        del5("メイン");
    }
}
ラムダ式に式本体を利用する

{}も省略することができます。(メソッドに式本体に利用することと同じ)

class Program
{
    static void Main(string[] args)
    {
        // ラムダ式を使用してDelをインスタンス化します。
        Action<string> del5 = name => Console.WriteLine($"{name}からの通知の受信");
        del5("メイン");
    }
}

C#7

(おまけ)他にもメソッドの中でしか使えないメソッド(ローカル関数)があります。

上記のような匿名メソッドは、使える場所が限定していますが、どこにでもかけます。
しかし、メソッドの中でしか使えないメソッドも存在します。

class Program
{
    static void Main(string[] args)
    {
        // ラムダ式を使用してDelをインスタンス化します。
        static void MyMethod(string name)
        {
            Console.WriteLine($"{name}からの通知の受信");
        }
        MyMethod("メイン");
    }
}

式本体を利用すると

class Program
{
    static void Main(string[] args)
    {
        // ラムダ式を使用してDelをインスタンス化します。
        static void MyMethod(string name) => Console.WriteLine($"{name}からの通知の受信");
        MyMethod("メイン");
    }
}

2019年12月16日C#,入門

Posted by hidepon