2017年4月11日火曜日

C# delegate(匿名メソッド、無名メソッド)Action、Func

c#のデリゲートについて、一度整理。

デリゲート。意味は「代理人」

「delegate」は色々な呼び方がある。
→匿名メソッド、無名メソッド、匿名関数。

「delegate」


使用例を見てみる。
         //匿名メソッドの「型」(引数と戻り値)の宣言のみ
        //TestMethod「型」がdelegateで宣言されている
        public delegate void TestMethod(string s);

        //ボタンクリック時イベント
        private void button1_Click(object sender, EventArgs e)
        {
            //delegateで宣言してある「TestMehod型」の変数に
            //匿名メソッドの処理をdelegateで書いて格納する
            TestMethod test1 = delegate (string msg)
            {
                MessageBox.Show(msg+"1");
            };

            //ラムダ式バージョン(処理内容は同じ)
            TestMethod test2 = (msg) => {
                MessageBox.Show(msg+"2");
            };

            //個々のメソッドとして使用できる。
            test1("メッセージ"); //「メッセージ1」と表示
            test2("メッセージ"); //「メッセージ2」と表示

        }
要するに、変数をメソッドとして扱いたいのである。

 匿名メソッドを作る為の型を作る必要があり、
「引数と戻り値の数」だけを宣言する為に「delegate」が使われている。
(c++だと関数ポインタ、std::function)


「Action」「Func」


「Action」と「Func」は「定義済みデリゲート」。
「delegate」の宣言が「Action」と「Func」で既に宣言してある為、
「delegate」の宣言が必要ない。
その為、当然使いやすい。
//「Action」は 「戻り値無し」
//「Func」は 「戻り値有り」
//引数や戻り値の型を<>内に指定。

//引数:void
//戻り値:void → 「Acton」を使う
Action act1 = () =>
{
  MessageBox.Show("a");
};

//引数:string
//戻り値:void → 「Acton」を使う
Action<string> act2 = (valueStr) =>
{
  MessageBox.Show(valueStr);
};

//引数:int,int
//戻り値:string → 「Func」を使う
Func<int, int, string> funcAdd = (x, y) =>
{
  return (x + y).ToString();
};

//処理結果
act1(); //「a」
act2("abc"); //「abc」
MessageBox.Show(funcAdd(1,2)); //「3」

デリゲートはその場限りのメソッドを書く事が出来る。
これを「定義済みデリゲート」を使って
「Action(戻り値無し、引数16個まで)」と
「Func(戻り値有り、引数16個まで)」を使う事により、
「delegate」の宣言がいらなくなり、
ラムダ式で書けば、かなりスマートに書く事が出来る。


ラムダ式で書いた匿名メソッド(delegate)の受け皿に
delegate型(「Action」「Func」型)の変数を使うイメージとなる。

delegate型の変数はメソッドとして使用できる。


他には「マルチキャストデリゲート」というのがある。
1つのデリゲート変数に、複数の無名メソッドを代入する事ができる。
これは、代入した無名メソッドの呼び出し順が保証されていない為、
あまり使わない方がよさそう…。

「MethodInvoker」の説明はしませんでした。
「Action」と「MethodInvoker」は同じ物です。
「Action」を利用しましょう。


以下サイトを参考にしました。
http://9cubed.info/article/delegate/

0 件のコメント:

コメントを投稿

↑Topへ