【お勉強記録】C#文法学び直し。匿名メソッド・ラムダ式
前回学んだデリゲートから、さらに匿名メソッドとラムダ式を自習。
匿名メソッドとラムダ式
匿名メソッドは名前のないメソッドのことで、デリゲートの生成においてその対象を直接埋め込む際に使うことができます。 匿名メソッドはさらに簡易的に書くことができて、その記法を「ラムダ式」といいます。 以下、実際に書いてみました。
using System; using System.Collections; using System.Collections.Generic; namespace test { class Program { static void Main(string[] args) { //匿名メソッド Func<int, int, int> addMethod = delegate(int left, int right) { return (left + right); }; //ラムダ式 Func<int, int, int> subMethod = ((int left, int right) => (left - right)); var mulMethod = new Func<int, int, int>((left, right) => (left * right)); var calcMethods = new List<Func<int, int, int>>(); calcMethods.Add(addMethod); calcMethods.Add(subMethod); calcMethods.Add(mulMethod); calcMethods.Add((int left, int right)=>left / right); foreach (var method in calcMethods) { Console.WriteLine(method(3, 2).ToString()); } Console.ReadLine(); } } }
一応、実行結果
5 1 6 1
ラムダ式はLinqでよく使うので、記法とかは甘い迷いませんが、結局なんなのって話はわりとうやむやな状態でしたので、改めて見直してよかったです。
ちなみに => の読みですが、「gose to」または「左辺を右辺に入力」と読むそうです。初めて知りました。いままで「矢印」とか「イカ」とか言ってました。
【お勉強記録】C#文法学び直し。デリゲート
デリゲート
delegate(デリゲート)はC#の型の一種で、メソッドへの参照を持つデータ型。 JavaScriptでfunctionも変数で受け渡しできるよっていうのと同じようなイメージを持っています(?)
using System; namespace test { class Program { static void Main(string[] args) { Example_delegate.TestDelegate(3, 2); Console.ReadLine(); } } public class Example_delegate { delegate int ExampleFunc(int x, int y); public static void TestDelegate(int x, int y) { ExampleFunc ef = Add; Console.WriteLine("メソッドAddを実行"); Console.WriteLine(ef(x, y).ToString()); ef = Sub; Console.WriteLine("メソッドSubを実行"); Console.WriteLine(ef(x, y).ToString()); ef = Mul; Console.WriteLine("メソッドMulを実行"); Console.WriteLine(ef(x, y).ToString()); } private static int Add(int x, int y) { return x + y; } private static int Sub(int x, int y) { return x - y; } private static int Mul(int x, int y) { return x * y; } } }
実行結果は以下の通り
メソッドAddを実行 5 メソッドSubを実行 1 メソッドMulを実行 6
宣言したデリゲートと引数と戻り値の型が同じメソッドへの参照を持つことができます。
Funcデリゲート Actionデリゲート
型パラメータをつかってもっとシンプルに書くことができるようです。
さっきのやつをFuncを使って書き換えてみると、こんな感じですかね?
using System; namespace test { class Program { static void Main(string[] args) { Example_delegate.TestFunc(3, 2); Console.ReadLine(); } } public class Example_delegate { public static void TestFunc(int x, int y) { Func<int, int, int> func = Add; Console.WriteLine("メソッドAddを実行"); Console.WriteLine(ef(x, y).ToString()); func = Sub; Console.WriteLine("メソッドSubを実行"); Console.WriteLine(ef(x, y).ToString()); func = Mul; Console.WriteLine("メソッドMulを実行"); Console.WriteLine(ef(x, y).ToString()); } private static int Add(int x, int y) { return x + y; } private static int Sub(int x, int y) { return x - y; } private static int Mul(int x, int y) { return x * y; } } }
Func<T, TResult>デリゲートは以下の構文になっているとのことです。
public delegate TResult Func<in T, out TResult>( T arg )
メソッドの引数の方を順に指定していって、最後に戻り値の型を指定するってことのようです。
Actionは戻り値がないときに使用されます。
パーフェクトC#ではデリゲートの利用イメージとして
の3つが出ています。
マルチスレッドのプログラムを書いた経験があまりないので、2はあまりイメージ付きません。これから勉強ですね…。