0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

C#でデリゲートを使って遊んだ

Last updated at Posted at 2020-02-25

C#でデリゲートやラムダ式など使い、いろいろ遊んでみました

program.cs
using System;

namespace CsLamTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Func<int> addDelegate=(        //(1)
                ()=> {                     //(1-1)
                    Console.WriteLine("初期化の関数から出力");     //(1-2)
                    return 0; 
                    }
                );

            f(                             //(2)
                () => {                    //(2-1)
                    Console.WriteLine("ラムダ式から出力");      //(2-2)
                    return 5 * 5;
                    },
                ref addDelegate           //(2-3)
            );
            f(                             //(3)
                delegate () {              //(3-1)
                    Console.WriteLine("デリゲートから出力");     //(3-2)
                    return 3 * 3;
                    },
                ref addDelegate          //(3-3)
            );
        }

        static void f(Func<int> func, ref Func<int> addDelegate)  //(4)
        {
            addDelegate += func;            //(4-1)
            Console.WriteLine(addDelegate());     //(4-2)
        }
    }
}

出力結果は

初期化の関数から出力
ラムダ式から出力
25
初期化の関数から出力
ラムダ式から出力
デリゲートから出力
9

解説

まずは(1)の部分

program.cs
            Func<int> addDelegate=(        //(1)
                ()=> {                     //(1-1)
                    Console.WriteLine("初期化の関数から出力");     //(1-2)
                    return 0; 
                    }
                );

(1)の行は、Func<int>(引数を取らずint型を返す関数)型のaddDelegateを定義しています。
addDelegateの初期化が(1-1)でラムダ式を用いて行われています。


次に(2)の部分

program.cs
            f(                             //(2)
                () => {                    //(2-1)
                    Console.WriteLine("ラムダ式から出力");      //(2-2)
                    return 5 * 5;
                    },
                ref addDelegate           //(2-3)
            );

(2)(4)の関数fを呼び出しています。
その第1引数Func<int> func(2-1)で示されたラムダ式を渡しています。
第2引数 ref Func<int> addDelegate(1)addDelegateを渡しています。・・・(2-3)の行。

(3)はラムダ式ではなく無名関数を渡しています。他は(2)と同じです。


次に(4)の部分

program.cs
        static void f(Func<int> func, ref Func<int> addDelegate)  //(4)
        {
            addDelegate += func;            //(4-1)
            Console.WriteLine(addDelegate());     //(4-2)
        }

(4-1)で、第1引数で渡されたfuncを、第2引数で渡されたaddDelegateに加えています。
デリゲートは、+=演算子を用いて、関数を連結できます。
連結された関数は、古いものから順番に実行されます。

実行の流れ

  1. まず(2)で関数fを呼び出し

  2. (4-1)addDelegate(2-1)のラムダ式を加える

  3. (4-2)addDelegate()を実行

    1. (1-2)が出力される
    2. (2-2)が出力される
    3. (2-1)のラムダ式の戻り値が出力される。
  4. 次に(3)で関数fを呼び出し

  5. (4-1)addDelegate(3-1)のデリゲートを加える

  6. 3.と同じ

    1. (1-2) (2-2) (3-2) が順番に出力される
    2. (3-1)のデリゲートの戻り値が出力される

今回のC#いじりで知ったこと

Func<int>には、ラムダ式も無名関数も渡せる、代入できる。
Console.WriteLine()では、デリゲートに複数の関数が+=で連結されていても、最後に実行される関数の戻り値のみ表示する。
デリゲートは値型だった。なので、refをつけています。

0
2
0

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
0
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?