// 下階層用テンプレート
#topicpath
----
//ここにコンテンツを記述します。

[[C#/いまさらヒトに聞けないこといろいろ/デリゲート]] で出てきた例(ちょっと整理しますが) をつかって、汎用的なデリゲート、Action/Funcの使い方をメモっておきます

**ちょっと整理 [#r31afff8]
[[C#/いまさらヒトに聞けないこといろいろ/デリゲート]]  のソースをもっとシンプルに整理してみます
 namespace ConsoleApplication1
 {
   delegate int Calculator(int x, int y);//delegateの宣言
   class Program
   {
     static void Main(string[] args)
     {
       calc(2, 3, methodPlus);
       calc(2, 3, methodMult);
     }
 
     public static void calc(int x, int y, Calculator instance)
     {
       int result = instance(x, y);
       Console.WriteLine(result);
     }
 
     public static int methodMult(int x, int y)
     {
       return x * y;
     }
     public static int methodPlus(int x, int y)
     {
       return x + y;
     }
   }
 }

** 汎用的なデリゲート? [#vac1968a]
** 汎用的なデリゲートFunc [#vac1968a]
上では
   delegate int Calculator(int x, int y);
というデリゲートを宣言しましたが、引数がint,int,戻り値がint、っていう汎用的なデリゲート
  Func<int, int, int>
を使うことで、ソースは以下のように書き直すことができます
 namespace ConsoleApplication1
 {
     //delegate int Calculator(int x, int y);  //コメントアウトしちゃう
     class Program
     {
         static void Main(string[] args)
         {
             calc(2, 3, methodPlus);
             calc(2, 3, methodMult);
         }
 
         public static void calc(int x, int y, Func<int, int, int> instance)
         {
             int result = instance(x, y);
             Console.WriteLine(result);
         }
 
         public static int methodMult(int x, int y)
         {
             return x * y;
         }
         public static int methodPlus(int x, int y)
         {
             return x + y;
         }
     }
 }
ソースからデリゲートの宣言を消すことが出来ました。こう書くと、いかにも関数を渡してるってかんじになりますねぇ。

**いろいろな書き方 [#a22e8f59]

これら、全部おんなじ意味です
 calc(2, 3, methodPlus);   // メソッドを渡す
 calc(2, 3, new Func<int, int, int>(methodPlus));   // newして、渡す
 calc(2, 3, new Func<int, int, int>(delegate(int x, int y) { return x + y; }));   // メソッドをその場で定義
 calc(2, 3, new Func<int, int, int>((int x, int y) => { return x + y; }));   // ラムダ式
 calc(2, 3, (int x, int y) => { return x + y; });   // ラムダ式で、デリゲート名を省略
 calc(2, 3, (x, y) => { return x + y; });   // ラムダ式は型を省略できる
 calc(2, 3, (int x, int y) => x + y);



**戻り値のない汎用デリゲート Action [#def8ee04]
つぎにActionデリゲートですが、こちらは戻り値のないFuncってかんじです

 using System;
 using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 
 namespace ConsoleApplication1
 {
   public class Program
   {
     static void Main(string[] args)
     {
       new Program().execute();
     }
 
     public void StringAction(string str)
     {
       Console.WriteLine("StringAction method start.");
       Console.WriteLine(str);
       Console.WriteLine("StringAction method end.");
     }
 
     public void execute()
     {
       // GenericsなdelegateをStringとして宣言
       Action<String> StringActionDele = new Action<String>(StringAction);
       //Action<String> StringActionDele = StringAction; // <-こういう書き方もしていい
       // delegate経由でメソッドを実行
       StringActionDele("StringActionDeleを直接呼び出しました");
 
       // メソッドの引数にdelegateインスタンスを渡すこともできる
       executeAction(StringActionDele);
 
       // Anonymousな感じで直接定義してもいい
       executeAction(
         new Action<String>(delegate(String str)
       {
         Console.WriteLine("Anonymous Delegate method start.");
         Console.WriteLine(str);
         Console.WriteLine("Anonymous Delegate method end.");
       })
       );
 
       // 最後はラムダ式。Actionなくなった。引数ひとつでvoidを戻すメソッドを
       // 渡すから、よろしくねって感じになる
       executeAction((str) =>
       {
         Console.WriteLine("Delegate method start.");
         Console.WriteLine(str);
         Console.WriteLine("Delegate method end.");
       });
 
       List<string> stringList = new List<string>();
       stringList.Add("こんにちは");
       stringList.Add("さようなら");
       stringList.ForEach(StringActionDele); // このメソッドで「処理」を渡してる
     }
 
     void executeAction(Action<String> actionDelegate)
     {
       actionDelegate("StringActionDeleをexecuteAction メソッドから呼び出しました");
     }
   }
 }







**関連リンク [#kb5fb20d]
-C#/いまさらヒトに聞けないこといろいろ/デリゲート
-[[C#と諸々 今更 Func デリゲートや Action デリゲートについて一言>http://csharper.blog57.fc2.com/blog-entry-252.html]]
-[[Action(T) デリゲート (System)>http://msdn.microsoft.com/ja-jp/library/018hxwa8.aspx]]
-[[Func(TResult) デリゲート (System)>http://msdn.microsoft.com/ja-jp/library/bb534960]]
-[[ジェネリックなメソッドやデリゲートがもたらす新スタイル − @IT>http://www.atmarkit.co.jp/fdotnet/special/generics02/generics02_02.html]]




----
この記事は
#vote(おもしろかった,そうでもない)

#comment
#topicpath


SIZE(10){現在のアクセス:&counter;}

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS