// 下階層用テンプレート #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;}