LoginSignup
82
75

More than 1 year has passed since last update.

C# デリゲートについて

Last updated at Posted at 2018-06-23

tl;dr(まとめ)

C#のデリゲートは、 引数として関数を1つ受けとるデータ型(参照型) の一種です。

C#には他にもnewキーワードで生成するデータ型としてクラス、構造体があります。

C#のデリゲートは、+, - 演算子を持ち、一つのデリゲート変数に複数のデリゲートを登録することが出来、 マルチキャスト と呼ばれる機能を持ちます。
(これが、C#のデリゲートの特筆すべき機能だと思います。)

書いたこと

  1. デリゲートの宣言
  2. デリゲートの生成と実行
    1. newキーワドによる生成
    2. 匿名メソッドによる生成
    3. ラムダ式による生成
  3. デリゲートの+-演算 (マルチキャスト)

デリゲートの宣言

デリゲートの宣言
delegate 戻り値の型 デリゲート名 (関数が引き受ける仮引数);

例: 「2つのint型の引数を受け取りint型の値を返す関数」のデリゲート宣言

Calculateデリゲートの宣言
// Calculateデリゲートの宣言
delegate int Calculate (int a, int b);
  • 仮引数名が要ることが残念ですね。

デリゲートの生成と実行

newキーワードによる生成

newキーワードによるデリゲートの生成
using System;

// デリゲートの宣言
delegate void Printer (string s);

class Test {
    public static void Main() {
        // デリゲートの生成
        Printer print = new Printer(Console.WriteLine);
        // デリゲートの実行
        print("Hello World");
    }
}
  • 引数としてクラスメソッド、もしくはインスタンスメソッドを受け取る

匿名メソッドによる生成

匿名メソッドによるデリゲートの生成
using System;

// デリゲートの宣言
delegate void Printer (string s);

class Test {
    public static void Main() {
        // デリゲートの生成
        Printer print = delegate (string s) {
            Console.WriteLine(s);
        };
        // デリゲートの実行
        print("Hello World");

        // 匿名メソッドはデリゲート変数に代入することも可能
        print = delegate (string s) {
            Console.WriteLine($"You inputed \"{s}\"");
        };
        print("I'm fine");
    }
}
/* 実行結果
Hello World
You inputed "I'm fine"
*/
  • delegateキーワードを使うことで匿名メソッドを定義することが出来る
  • 匿名メソッドはデリゲートの初期化もしくはデリゲート変数に代入する事ができる。
  • つまり匿名メソッドはデリゲートを生成する

ラムダ式による生成

ラムダ式によるデリゲートの生成
using System;

// デリゲートの宣言
delegate void Printer (string s);

class Test {
    public static void Main() {
        Printer print = (string s) => {
            Console.WriteLine($"You inputed \"{s}\"");
        };
        print("I'm fine");
    }
}
  • ラムダ式も匿名メソッドと同じ様に、デリゲート変数の初期化、もしくは代入を行うことが出来る。
  • つまりラムダ式もデリゲートを生成する

デリゲートの+-演算 (マルチキャスト)

C#のデリゲートは一つのデリゲート変数に複数のデリゲートを登録することが出来ます。
マルチキャスト機能 と呼ばれます。)

マルチキャストによる複数のデリゲートの登録
using System;

// デリゲートの宣言
delegate void Calculator (int other);

class Test {
    public static void Main() {
        var i = new Integer(5);
        // 一つのデリゲート変数に複数のデリゲートを登録できる
        var calculator = new Calculator(i.Add) + new Calculator(i.Sub) + new Calculator(i.Mul);
        // デリゲートを実行
        calculator(5);

        Console.WriteLine("-- 引き算を削除 --");

        // 登録したデリゲートを削除することが出来る 
        calculator -= new Calculator(i.Sub);
        // デリゲートを実行
        calculator(10);
    }
}

class Integer {
    public int val;
    public Integer(int n) {
        val = n;
    }
    public void Add(int n) {
        Console.WriteLine($"足し算の結果は: {val + n}です。");
    }
    public void Sub(int n) {
        Console.WriteLine($"引き算の結果は: {val - n}です。");
    }
    public void Mul(int n) {
        Console.WriteLine($"掛け算の結果は: {val * n}です。");
    }
}
/* 実行結果
足し算の結果は: 10です。
引き算の結果は: 0です。
掛け算の結果は: 25です。
-- 引き算を削除 --
足し算の結果は: 15です。
掛け算の結果は: 50です。
*/
  • + 演算子を使って追加登録
  • - 演算子を使って登録から削除

Appendix

匿名メソッド

匿名メソッドの定義

delegate (仮引数) {
    // 式
}
  • 生成するデリゲートの型は、コンパイラが推論してくれる

ラムダ式

ラムダ式
(仮引数) => {
    // 式
}
  • 生成するデリゲートの型は、コンパイラが推論してくれる

参照

猫でもわかるC#プログラミング 第3版

参照型 (C# リファレンス)

82
75
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
82
75