#author("2019-10-14T14:31:27+08:00","default:Admin","Admin") 言語セクション C#のラムダ式(Lambda)を紹介します。 概要 † ラムダ式は式とステートメントを含めることができる匿名関数であり、デリゲート型または式ツリー型を作成するために使用できます。
書き方 †ラムダ式 x => x * x は、「x を x * x に入力」と読みます。この式は、次のようにデリゲート型に割り当てることができます。~ delegate int del(int i); static void Main(string[] args) { del myDelegate = x => x * x; int j = myDelegate(5); //j = 25 } ツリー型を作成するには Expression<del> myET = x => x * x; 式形式のラムダ †右辺に式があるラムダ式を式形式のラムダと呼びます。 式形式のラムダは、式ツリー (C# および Visual Basic)の構築に幅広く使用されます。~
(input parameters) => expression
(x, y) => x == y
(int x, string s) => s.Length > x
() => SomeMethod() ステートメント形式のラムダ †
(input parameters) => {statement;}
delegate void TestDelegate(string s); … TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello"); 匿名メソッドと同様、ステートメント形式のラムダを使用して式ツリーを作成することはできません。 標準クエリ演算子でのラムダ †標準クエリ演算子の多くが、汎用デリゲートの Func<T, TResult> ファミリに属する型の入力パラメーターを持ちます。 Func<T, TResult> デリゲートは型パラメーターを使用して入力パラメーターの数と型、およびデリゲートの戻り値の型を定義します。 Func デリゲートは、ソース データのセット内の各要素に適用されるユーザー定義の式をカプセル化する場合に非常に便利です。 たとえば、次のデリゲート型を public delegate TResult Func<TArg0, TResult>(TArg0 arg0) このデリゲートを Func<int,bool> myFunc としてインスタンス化できます。int は入力パラメーター、bool は戻り値です。 戻り値は必ず最後の型パラメーターで指定されます。 Func<int, string, bool> は 2 つの入力パラメーター (int と string) と戻り値の型 bool を持つデリゲートを定義しています。 次の Func デリゲートを呼び出すと、入力パラメーターが 5 に等しいかどうかを示す true または false が返されます。 Func<int, bool> myFunc = x => x == 5; bool result = myFunc(4); // returns false たとえば System.Linq.Queryable で定義された標準クエリ演算子において、引数型が Expression<Func> の場合もラムダ式を使用できます。 Expression<Func> 引数を指定すると、ラムダは式ツリーにコンパイルされます。 標準クエリ演算子である Count メソッドを次に示します。 int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddNumbers = numbers.Count(n => n % 2 == 1); 入力パラメーターの型はコンパイラが推論できますが、明示的に指定することもできます。 この特定のラムダ式は、2 で除算したときに剰余が 1 になる整数 (n) をカウントします。 次のメソッドは、配列 numbers 内の "9" の左側にある要素をすべて含むシーケンスを作成します。これは、"9" がシーケンス内で条件を満たさない最初の数値だからです。 var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6); 次の例は、複数の入力パラメーターを括弧で囲んで指定する方法を示しています。 このメソッドは、値がその位置よりも小さい数値が出現するまで配列 numbers に含まれるすべての要素を返します。 var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index); 使用例 †下記のようなクラスがあります。 public class Person { public string Name { get; set; } public int Age { get; set; } } リストのオブジェクトを作成します。 List<Person> PersonList = <...>; Sort †リスト内の要素を並び替え PersonList.Sort((x, y) => { if (x.Age > y.Age) return -1; else if (x.Age == y.Age) return 0; else return 1; }); Count †指定する条件に満たす要素の個数を取得する PersonList.Count(x => { return x.Age = 20; }); PersonList.Count( x => x.Age = 20 ); Select †要素を新しい値へ射影する List<int>のオブジェクトをList<object>へキャスト List<int> list = new List<int>(); //... list.Select(x => (object)x).ToList(); list.Select<int, object>(x => (object)x).ToList(); OrderBy †Dictionary<T> オブジェクトで例として説明します。 Dictionary<Person, int> list = new Dictionary<Person, int>(); //「Person」クラスの「Name」プロパティの値による並ぶ list.OrderBy(key => (key.Key as Person>.Name)); //値による並ぶ list.OrderBy(key => key.Value); Cast †ListBoxのItemsをstring[] へ変換する this.listBox1.Items.OfType<string>().ToArray() イベントの実装に使用例 †TextBoxの「TextChanged」イベントの実装例 this.textBox1.TextChanged += (x, y) => { this.textBox1.Text = "Changed"; }; 超多機能のアクセス解析が永久無料! コメント: |