Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
52
Help us understand the problem. What is going on with this article?
@ysn

C# デリゲートについて

More than 1 year has passed since last update.

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 am 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# リファレンス)

52
Help us understand the problem. What is going on with this article?
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ysn
はてな https://yossan.hatenablog.com/

Comments

No comments
Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account Login
52
Help us understand the problem. What is going on with this article?