C#のデリゲートまとめ!型とFuncとActionと!

この記事は約 4 分で読めます。

今回C#の勉強でデリゲートというものを知っていろいろ調べたので、備忘録がてら書いていこうと思う。

デリゲートとは?

そもそもデリゲートとは何ぞや?という話なんですが、すごく簡単に言うと引数に関数を指定できるというもの。

この引数に関数を指定するというのが、どんな場合にうれしいのかというと、おそらく前後の処理は同じで中身の処理が違う場合だと思う。

このデリゲートには、C#の場合主に以下の使い方があるらしい。

  1. デリゲート型を宣言していくパターン
  2. Func<>で インスタンス生成を省略するパターン
  3. Action<>でインスタンス生成を省略するパターン
  4. Predicate<>を使ってラムダ式みたいなのを自作するパターン

今回はこの中で比較的性質が似ている1~3について書いていこうと思う。

デリゲート型を宣言していくパターン

デリゲート型を宣言するパターンでは、自分でクラスやメソッドを宣言するときのように、デリゲート型を宣言する。

このデリゲート型の使い方はメソッドとかと同じ感じ。

namespace ConsoleApplication2
{
    class Program
    {

        static void Main(string[] args)
        {
            var myDele = new TestDelegate();
            myDele.Execute();
            Console.ReadLine();
        }
    }

    delegate int myDelegate(int x, int y);

    class TestDelegate
    {
        public void Execute()
        {
            myDelegate AddDele = Add;
            myDelegate SubDele = Sub;
            MessageShow(2, 2, AddDele);
            MessageShow(2, 2, SubDele);
        }
        public void MessageShow(int x,int y,myDelegate myDeli)
        {
            Console.WriteLine(myDeli(x, y));
        }

        public int Add(int x,int y)
        {
            return x + y;
        }
        public int Sub(int x, int y)
        {
            return x - y;
        }

    }
}

Func<>で同じことをやってみる。

デリゲートにおけるFunc<>とは、引数ありの関数のことで、<>の中身は以下のようになっている。

<引数1,引数2,・・・・,戻り値>

なので下記の場合だと、引数1と引数2がintで戻り値がintの関数をデリゲートすることができる。

またFuncでは上記「new Delegate」を言う部分を省略でき、引数にそのままFunc<>と書くことができる。

namespace ConsoleApplication2
{
    class Program
    {

        static void Main(string[] args)
        {
            var myDele = new TestDelegate();
            myDele.Execute();
            Console.ReadLine();
        }
    }

    delegate int myDelegate(int x, int y);

    class TestDelegate
    {
        public void Execute()
        {
            MessageShow(2, 2, Add);
            MessageShow(2, 2, Sub);
        }
        public void MessageShow(int x,int y,Func<int,int,int> myDeli)
        {
            Console.WriteLine(myDeli(x, y));
        }

        public int Add(int x,int y)
        {
            return x + y;
        }
        public int Sub(int x, int y)
        {
            return x - y;
        }

    }
}

Action<>で同じことをやってみる。

Funcでは戻り値ありの場合のデリゲートと書いたが、Action<>は戻り値無しの場合に使われる。

なので、Action<>の<>の中身はすべて引数。

下記の場合は引数1と引数2がintの戻り値のない関数をデリゲートできる。

注目してほしいのは、AddとSubの関数の中身。

これまではReturnになっていたが、Actionでは戻り値がないので、Console.WriteLineになっている。

namespace ConsoleApplication2
{
    class Program
    {

        static void Main(string[] args)
        {
            var myDele = new TestDelegate();
            myDele.Execute();
            Console.ReadLine();
        }
    }

    delegate int myDelegate(int x, int y);

    class TestDelegate
    {
        public void Execute()
        {
            MessageShow(2, 2, Add);
            MessageShow(2, 2, Sub);
        }
        public void MessageShow(int x,int y,Action<int,int> myDeli)
        {
            myDeli(x, y);
        }

        public void Add(int x,int y)
        {
            Console.WriteLine(x + y);
        }
        public void Sub(int x, int y)
        {
            Console.WriteLine(x - y);
        }

    }
}

上記の結果と所感

ちなみに上記3つの実行結果はすべて以下の形になる。

4
0

所感

デリゲートは関数型言語特有の技術ということであるが、PHPでも関数を引数として渡し場合もあるらしいので、引数に関数を指定するというのは割とメジャーな技術なのかもしれない。

デリゲートをマスターすることでいろいろな部分で役立ちそうなので、使っていきたいなーーーと思う今日この頃だった。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

CAPTCHA