Lambda表達(dá)式和Linq查詢淺析
Linq有很多值得學(xué)習(xí)的地方,這里我們主要介紹Lambda表達(dá)式和Linq查詢,包括介紹Filter方法等方面。
Lambda表達(dá)式和Linq查詢
接下來我們通過一個(gè)例子來看一下Lambda表達(dá)式和Linq查詢的關(guān)系:我們現(xiàn)在想給ClassCollection增加一個(gè)過濾方法,方法的目的是能夠過濾返回班級(jí)名稱為“終極一班”的集合來。
1.首先給MyExtention增加這么一個(gè)靜態(tài)方法:
- public static ClassCollection Filter(this ClassCollection classes)
- {
- var newnewlist = new ClassCollection();
- foreach (var item in classes)
- {
- if (item.Name=="終極一班")
- {
- newlist.Add(item);
- }
- }
- return newlist;
- }
- private static void LambdaLinq()
- {
- var classes = GetClasses();
- //var students = GetStudents();
- //0 原始版本
- var result = classes.Filter();
- foreach (var item in result)
- }
- Console.WriteLine(item.ID+ " " + item.Name);
- }
- }
- //相關(guān)的工廠方法:
- static ClassCollection GetClasses()
- {
- return new ClassCollection{
- new Class(1){ Name = "終極一班"},
- new Class(2){ Name = "終極二班"},
- };
- }
2.現(xiàn)在需求發(fā)生了變化,需要上面的紅色部分需要發(fā)生變化,也就是說我們希望這個(gè)查詢條件可以在我們調(diào)用Filter方法的時(shí)候動(dòng)態(tài)的指定,這時(shí)候我們可以把這個(gè)變化封裝成一個(gè)接口,當(dāng)然還可以封裝成一個(gè)委托,這是.net的非常好用的獨(dú)有特性,委托的最直接的作用可以把一個(gè)具體的方法引用封裝成一個(gè)變量傳遞。好,開始變形!
- delegate bool FilterHandler(Class c);
- //注意這個(gè)要放到namespace下面,不要放到Program類里面
- public static ClassCollection Filter(this ClassCollection classes,FilterHandler f)
- {
- var newnewlist = new ClassCollection();
- foreach (var item in classes)
- {
- if (f(item))
- {
- newlist.Add(item);
- }
- }
- return newlist;
- }
- static bool F(Class c)
- {
- return c.Name == "終極一班";
- }
- private static void LambdaLinq()
- {
- var classes = GetClasses();
- // C#1.0 使用委托封裝過濾條件
- FilterHandler f=new FilterHandler(F);
- var result = classes.Filter(f);
- foreach (var item in result)
- {
- Console.WriteLine(item.ID+ " " + item.Name);
- }
- }
我們聲明了一個(gè)委托FilterHandler,只要滿足這個(gè)委托的方法我們都可以傳遞給Filter方法,這樣就實(shí)現(xiàn)了動(dòng)態(tài)的改變查詢條件的目的,F(xiàn)方法內(nèi)部可以是任意的查詢條件比如return c.Name != "終極一班";同時(shí)我們不需要改變Filter方法內(nèi)部穩(wěn)定的部分。
3.c#2.0里面也支持直接把一個(gè)方法傳給一個(gè)委托,但本質(zhì)上也是編譯器把方法轉(zhuǎn)換成了一個(gè)委托,例如上面:
- private static void LambdaLinq()
- {
- var classes = GetClasses();
- // C#2.0 直接傳遞方法
- var result = classes.Filter(F);
- foreach (var item in result)
- {
- Console.WriteLine(item.ID+ " " + item.Name);
- }
- }
4.C#2.0里面有個(gè)新特性,叫匿名方法,我們可以直接傳遞匿名方法:
- private static void LambdaLinq()
- {
- var classes = GetClasses();
- // C#2.0 傳遞匿名方法
- var result = classes.Filter(delegate(Class c) { return c.Name == "終極一班"; });
- foreach (var item in result)
- {
- Console.WriteLine(item.ID+ " " + item.Name);
- }
- }
好,變形到這里,我們發(fā)現(xiàn)這個(gè)匿名其實(shí)不僅僅可以給我們帶來不用給方法命名的好處,在這個(gè)方法內(nèi)部我們還可以使用外部上下文環(huán)境的變量成員,這個(gè)特性也叫“閉包(Closure)”,JavaScript也支持這個(gè)特性,比如:
- private static void LambdaLinq()
- {
- var classes = GetClasses();
- string className = "終極一班";
- // C#2.0 傳遞匿名方法
- var result = classes.Filter(delegate(Class c) { return c.Name == className; });
- foreach (var item in result)
- {
- Console.WriteLine(item.ID+ " " + item.Name);
- }
- }
以上介紹Lambda表達(dá)式和Linq查詢。
【編輯推薦】