【C#】Func を定義して使用する方法

当ブログでは、これまでにデリゲートに関連する「Predicate」「Action」について解説を多く行ってきました。これまでの内容を確認していなければ、以下の記事を読んで「Predicate」「Action」を学んでおきましょう。

今回、この記事で紹介するのは「Func」と呼ばれるものです。「Predicate」「Action」と続いた最後のデリゲートのテンプレートのようなものになります。

「Func」とは引数と戻り値を指定できるデリゲートのようなものです。この「Func」を覚えてしまえば戻り値を持つ「delegate ~」と記述する必要がなくなります。これによって処理のカプセル化がぐっと簡単になりました。

Funcとは

まずはFuncの特徴から紹介していきます。これまでの「Predicate」や「Action」に近いものがあります。

  • Func<T1, T2, …, Tresult>の形式で記述する
  • 複数の型を記述する場合はカンマ区切りで記述する
  • Tresultの型が戻り値の型となる
  • Tresultの型と同じ匿名メソッドでも記述できる

C#のdllに記載されたコメントは以下のようになっています。

1 つのパラメーターを受け取って TResult パラメーターに指定された型の値を返すメソッドをカプセル化します。

サンプル程度になりますが、匿名メソッドとFuncの書き方は以下のように異なります。

//delegate 
delegate bool LengthCheck(string s, int len);

//Func
Func<string, int, bool> LengthCheck

Funcでは「<>」内の引数が順に続き最後が戻り値となりますので、「LengthCheck」メソッドは第一引数がstring、第二引数がint、そして戻り値がbool型になります。ここまで分かれば十分ですので、早速、実践的な内容に入っていきましょう。

C#でFuncを書く方法

ここからは実際にサンプルコードを見ながら、Funcの書き方を解説していきます。新規のコンソールアプリケーションを作成して、以下のソースコードを記述してみましょう。

using System;

namespace App01
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("数値を入力してください。");
            int input = Convert.ToInt32(Console.ReadLine());

            //Funcを起動するメソッドを呼び出す
            GetMessage(x => x > 9 ? "10以上の数です" : "10未満の数です", input);
            Console.ReadLine();
        }

        //Funcを起動するメソッド
        private static void GetMessage(Func<int, string> func, int input)
        {
            //funcを起動してメッセージを受け取り出力する
            string message = func(input);
            Console.WriteLine(message);
        }
    }
}

Funcを定義している箇所は以下になります。今回のFuncはint型を引数にとり、string型を戻り値とするようにしています。GetMessageの中では第一引数のFuncを実行して、受け取ったメッセージを画面に出力するだけの簡単な処理となっています。

private static void GetMessage(Func<int, string> func, int input)

このメソッドを呼び出しているのが「Main」メソッド内のいかに該当する箇所になります。三項演算子を用いて、数字(引数)の値が10以上かどうかを判定してメッセージを返すような仕組みにしています。

//Funcを起動するメソッドを呼び出す
GetMessage(x => x > 9 ? "10以上の数です" : "10未満の数です", input);

ラムダ式の部分だけ抜き出すと以下になります。xを引数としています。これはFunc<int, string>のint部分であることはわかるかと思います。また「x =>」と記述しているため「return …」の記述は不要となっています。

x => x > 9 ? "10以上の数です" : "10未満の数です"

あとは三項演算子の結果によって返すstring型の値を切り替えているだけです。ここは普通のC#の世界ですので問題はないかと思います。ここまででFuncの解説は終了です。