朋友,或許你了解委托,熟悉監視者模式,常用lambda表達式或者linq查詢,自定義過擴展方法,但假如你沒留意過他們之間的關系,不清楚委托是如何演變為lambda表達式,再如何導出linq語句的,又或者想了解以上知識內容的,那么就進來一起學習本節吧。本節我們要了解委托和監視者模式,然后再由匿名委托一步步導出lambda表達式,最后用lambda表達式結合擴展方法來舉例闡釋Linq查詢。這節是委托到Linq集成化查詢的小小推導,希望能對大家有所幫助。本人新手上路,難免紕漏重重,還望大伙兒海涵。更希望大家能提出寶貴意見,鄙人感激不盡。下面咱們就一起探討學習本節內容吧……
委托:
用Delegate 關鍵字聲明委托,下面要引用MSDN上的一段內容,它們概括出我不能解釋的隱含知識:委托是一種引用方法的類型。一旦為委托分配了方法,委托將與該方法具有完全相同的行為。委托方法的調用可以像其他任何方法一樣,具有參數和返回值。委托是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指針類似。與 C 中的函數指針不同,委托是面向對象的、類型安全的和保險的。委托的類型由委托的名稱定義。下面的示例聲明了一個名為 Del 的委托,該委托可以封裝了采用字符串作為參數並返回 void類型 的方法。public delegate void Del(string message); 下面寫個委托的例子來幫組大家理解,重點是要理解其中為什么可以把方法名賦值給委托對象。可以參考例子:int a = 0;因為等號左右同為數值類型,類型一致,所以可以賦值。

1 using System; 2 //這個委托的名字是MyDel,委托的類型是MyDel 3 //這個委托代表了一系列函數,這一些函數必須是沒有返回值,沒有參數。 4 public delegate void MyDel(); 5 //這個委托代表了一系列函數,這一系列函必須是返回值為String,並且有一個String類型的參數。 6 public delegate void MyDel2(string name); 7 //這個委托代表了一系列函數,這一系列函數必須是返回值為String,並且有一個String類型的參數。 8 public delegate int MyDel3(int a,int b); 9 public class StudyDelegate 10 { 11 public static void Main() 12 { 13 //創建委托對象的兩種方法: 14 //1.如果使用new關鍵字來創建委托對象,則必須使用一個函數初始化這個委托對象。 15 MyDel2 my = new MyDel2(print); 16 //2.如果不使用new關鍵字來創建委托對象,則可以直接賦值。 17 MyDel2 m1 = print2; 18 //委托和他封裝的方法具有相同的功能。 19 //my("ss"); 20 //m1("ww"); 21 //4,既然委托代表了一系列函數,那么一個委托對象可以承接多個函數。 22 my += print2; 23 my("ss"); 24 //在承接的函數集中刪減函數 25 my -= print2; 26 my("ss"); 27 28 29 } 30 public static void print(string name) 31 { 32 33 Console.WriteLine("print----------"+name); 34 35 } 36 public static void print2(string n) 37 { 38 Console.WriteLine("2222----------"+n); 39 } 40 41 }
既然我們初步了解了委托,知道委托的定義和形式,那么咱們再一起學習一下委托的常用環境:我舉幾個簡單小例子來引如今天所要說的委托,仔細體會其中的區別:
1.

1 using System; 2 public class StudyDelegate1 3 { 4 public static void Main() 5 { 6 SayHello("中國"); 7 } 8 public static void SayHello(string county) 9 { 10 if(country=="中國") 11 { 12 Say(content); 13 } 14 if(country=="USA") 15 { 16 Say(content); 17 } 18 if(country=="England") 19 { 20 Say(content); 21 } 22 23 } 24 }
如果有必要加入新的成員國家,則整個程序都要變動,程序健壯性很差。下面我稍加修改:
2.

1 using System; 2 //相比上面方法,抽象出了枚舉 3 public enum Country 4 { 5 中國,American,England,Japan,Koran 6 } 7 public class StudyDelegate1 8 { 9 public static void Main() 10 { 11 SayHello("中國"); 12 } 13 public static void SayHello( Country country,string content) 14 { 15 if(country== Country."中國") 16 { 17 Say(content); 18 } 19 if(country==Country."USA") 20 { 21 Say(content); 22 } 23 if(country==Country."England") 24 { 25 Say(content); 26 } 27 28 } 29 //抽象出了共同的方法體 30 public void Say(string content) 31 { 32 Console.WriteLine(content); 33 } 34 }
加入新的成員國家時候,if語句內容,枚舉內容都要更改,健壯性依然很差,下面我用委托知識再稍加修改:
3.

1 using System; 2 public delegate void DelSay(string content); 3 public class StudyDelegate1 4 { 5 public static void Main() 6 { 7 //采用委托,根據不同國家調用不同內容 8 SayHello("你好",CSay); 9 SayHello("Hello",ESay); 10 11 } 12 //方法主題部分 13 public static void SayHello(string content,DelSay ds) 14 { 15 ds(content); 16 17 } 18 public static void CSay(string content) 19 { 20 Console.WriteLine(content); 21 } 22 public static void ESay(string content) 23 { 24 Console.WriteLine(content); 25 } 26 }
上述委托是當做參數來傳遞的,傳遞之后就可以當做方法使用。封裝了共同方法,又傳入委托做參數來調用方法后,當添加新的成員國家,我們就不必再更改方法的主題部分,相比之上的兩個程序,它安全性、可拓展性就好很多。了解了什么是委托了,我們就要來看看什么是監視者模式。
監視者模式:
監視者模式是在微軟平台上大量存在的一種模式,通俗一點它就是事件,事件就是監視者模式。比如生活中,你睡覺的時候委托同學上課叫醒你,這就是一個監視者模式,你是被監視者,是委托方,同學是被委托方,監視者。下面給大家舉個例子:考試的時候自己委托父母監視自己,考的好的話讓父母獎勵,考差了則受罰的監視者模式:

1 using System; 2 public delegate void Del(); 3 4 public class StudyObserver 5 { 6 public static void Main() 7 { 8 //創建對象 9 Student s = new Student(); 10 //Parent pp = new Parent(); 11 //Parent1 pp1 = new Parent1(); 12 13 //s發布兩個獎勵委托 14 s.p = ()=>{Console.WriteLine("sss");}; 15 s.k =()=>{Console.WriteLine("wwww");}; 16 //s發布兩個個懲罰委托 17 //s.k = pp.KKit; 18 //s.k+=pp1.KKit; 19 //s開始執行考試 20 s.Exam(); 21 } 22 } 23 /* 24 發布委托者 25 被監視方、 26 */ 27 public class Student 28 { 29 //聲明兩個委托變量 30 public Del p = null; 31 public Del k = null; 32 //執行考試(用循環語句模擬考試過程) 33 public void Exam() 34 { 35 for(int i=0;i<=100;i++) 36 { 37 if(i<60) 38 { 39 k(); 40 }else 41 { 42 p(); 43 } 44 } 45 } 46 } 47 /* 48 接受委托方 49 監視方 50 */ 51 public class Parent 52 { 53 //監視者的方法 54 public void PPrice() 55 { 56 Console.WriteLine("考的不錯,獎勵個饅頭"); 57 } 58 public void KKit() 59 { 60 Console.WriteLine("考的太差,面壁思過"); 61 } 62 } 63 /* 64 接受委托方 65 監視方 66 */ 67 //追加的監視者,因為委托可以承接多個函數 68 public class Parent1 69 { 70 public void PPrice() 71 { 72 Console.WriteLine("多獎勵一個饅頭"); 73 } 74 public void KKit() 75 { 76 Console.WriteLine("考的太差"); 77 } 78 }
平常生活中遇到的監視者模式的例子很多很多,像在visual studio中窗體的button等控件和窗體之間就是監視者模式,當點擊button控件時候,不是空間本身字節處理,而是通過form窗體 做出處理(單擊button按鈕后form窗體來做出反應,彈出對話框)。整個過程不是button自己處理事件,而是button按鈕委托form窗體來處理,這時候button就是委托方,form窗體就是監視方。監視者模式其實就是一種委托類型,了解了日常生活中的監視者模式,我們就來看看一種另類的委托------匿名委托…
匿名委托:
匿名委托也是一種委托,只不過沒有方法名,可以理解為用delegate代替了匿名委托的方法名,很多情況在不必要創建方法,需要臨時創建方法來調用時使用 ,下面例子能很好說明匿名委托的不同用法

1 using System; 2 public delegate void Delsing(); 3 public delegate int DelPlus(int a, int b); 4 public delegate string DelString(string a, int b); 5 public class StudyDelegate 6 { 7 public static void Main() 8 { 9 //委托 10 Delsing d = Sing; 11 d(); 12 //匿名委托 13 Delsing d1 = delegate(){Console.WriteLine("匿名委托");}; 14 d1(); 15 //帶參數且有返回值的匿名委托 16 DelPlus d2 = delegate(int j, int k){return j+k;}; 17 Console.WriteLine(d2(1,2)); 18 //帶參數且有返回值的匿名委托,當做參數來傳,然后調用函數實現功能 19 DelString d3 = delegate(string a, int b){return a+b;}; 20 Test(d3,"1+1=",2); 21 } 22 public static void Test(DelString del,string a, int b) 23 { 24 string str = del(a,b); 25 Console.WriteLine(str); 26 } 27 public static void Sing() 28 { 29 Console.WriteLine("I'm singing"); 30 } 31 public static void Print() 32 { 33 } 34 35 }
熟悉了匿名委托之后,我們就可以推導lambda表達式了,lambda表達式其實就是匿名委托的‘變種’:
lambda表達式:
lambda表達式其實就是匿名委托精簡之后的形式,在參數和方法體中間補上 ‘=>’(稱作goes to)來表示這是lambda表達式。下面來看一下lambda表達式具體例子:

1 using System; 2 public delegate void Delsing(int c); 3 public delegate int DelPlus(int a, int b); 4 public delegate string DelString(string a, int b); 5 public class StudyDelegate 6 { 7 public static void Main() 8 { 9 //匿名函數 10 //Delsing d1 = delegate(int c){Console.WriteLine(c);}; 11 //轉化lambda表達式時候要去掉delegate 加上=> 12 //Delsing d1 = (int c)=>{Console.WriteLine(c);}; 13 //一個參數的時候可以去掉括號,不論什么時候參數類型可以省略系統根據委托名自動判斷 14 Delsing d1 = c=>{Console.WriteLine(c);}; 15 //函數調用 16 //Test(d1,45); 17 Test(c=>{Console.WriteLine(c);},45); 18 19 /*-----下面委托到lambda表達式的一步步變形同上-------*/ 20 //匿名函數轉化為lambda表達式的最初形式 21 DelPlus d2 = (a,b)=>{int c = a+b;return c;} ; 22 //Test(d2,1,2); 23 Test((a,b)=>{int c = a+b;return c;},8,9); 24 //當有返回值,並且直接返回時候,匿名函數中{}可以換做(),並且省略return 25 DelPlus d3 = (a,b)=>(a+b); 26 //調用方法時候,最前面始傳的是委托對象,后面是參數 27 //Test(d3,6,5); 28 Test((a,b)=>(a+b),6,7); 29 30 31 DelString d4 = (a,b)=>(a+" "+b); 32 //Test(d4,"h",34); 33 Test((a,b)=>(a+" "+b),"h",45); 34 35 } 36 //函數的重載 37 public static void Test(Delsing d,int a) 38 { 39 d(a); 40 } 41 42 public static void Test(DelPlus d,int a,int b) 43 { 44 int c = d(a,b); 45 Console.WriteLine(c); 46 } 47 public static void Test(DelString d,string a ,int b) 48 { 49 string s = d(a,b); 50 Console.WriteLine(s); 51 } 52 53 }
看了上面例子后,相信你對lambda表達式已有初步印象,下面我做一下lambda表達式不同形式的小總結:

1 先定義一個Del開頭的委托 2 1. public delegate void Del1(); 3 匿名委托 4 Del1 d1 = delegate(){Console.WriteLine("ss");}; 5 d1 = ()=>{Console.WriteLine("ss");}; 6 //由於沒有參數,那么()不能省略 7 2.public delegate int Del2(); 8 Del2 d2 = delegate(){return 1;}; 9 d2 = ()=>{return 1;}; 10 //如果是直接返回,換句話說就是沒有業務邏輯處理,也就是只有一條返回語句,可以把{}換成()同時去掉return關鍵字 11 d2=()=>(1); 12 //如果方法體中有業務邏輯,則必須使用{} 13 d2=()=>{if(2>1){return 1;}else{return 2;}}; 14 3.public delegate void Del3(string a); 15 Del3 d3 = delegate(string a){Console.WriteLine(a);}; 16 d3 = (stirng a)=>{Console.WriteLine(a);}; 17 //可以把參數的類型給去掉,因為系統會自行的判斷參數的類型,畢竟是把這個lambda賦值給了對應的委托。 18 d3 = (a)=>{Console.WriteLine(a);}; 19 //如果說只有一個參數,則不需要() 20 d3 = a =>{Console.WriteLine(a);}; 21 4.public delegate string Del4(string a); 22 Del4 d4 = delegate(string a){string c = a+78;return c;} 23 d4 = (string a)=>{a+78;return a;}; 24 d4 = a=>{a+78;return a;} 25 d4 = a=>("gg"); 26 5.public delegate int Del5(int a,int b); 27 Del5 d5 = delegate(int a,int b){return a+b;}' 28 d5 = (int a,int b)=>{return a+b;}; 29 d5 = (a,b)=>{return a+b;}; 30 //如果參數個數是大於1的時候,不能把小括號給去掉 31 d5 = (a,b)=>(a+b); 32 d5 = (a,b)=>a+b; 33 d5 = a=>a+1;
lambda表達式的內容就先說到這里,如果大家還要了解更多相關知識,請查看博客園中其他更多有關文章。下面我們小看一下linq
Linq語言集成化查詢:
linq不同與結構化查詢語言(SQL)它不僅可以查詢數據而且可以查詢對象。
LINQ 的官方中文名稱為“.NET 語言集成查詢”,英文全稱為 Language-Integrated Query。它提供了類似於 SQL 語法的遍歷,篩選與投影功能,LINQ 不僅能完成對於對象的查詢,它可以透過 DLINQ 操縱數據庫,或是透過 XLINQ 控制 XML.我們來比較下兩個不同方法來求出數組中大於20的數據的例子:
1.常用方法:結合上一節講述的泛型知識,可以把數據放入泛型列表中,再用foreach語句循環輸出:

1 using System; 2 using System.Collections.Generic; 3 public class StudyLinq 4 { 5 public static void Main() 6 { 7 int[] a = {2,23,25,14,1,80,16,26,30}; 8 //求出數組中大於20的數據 9 List<int> list = new List<int>(); 10 foreach(int b in a) 11 { 12 if(b>20) 13 { 14 list.Add(b); 15 } 16 } 17 foreach(int c in list) 18 { 19 Console.WriteLine(c); 20 } 21 } 22 }
2.用IEnumerable的Where擴展方法,通過lambda表達式,精簡程序執行過程,需要導入命名空間:using System.Linq;

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyLinq 5 { 6 public static void Main() 7 { 8 int[] a = {2,23,25,14,1,80,16,26,30}; 9 //求出數組中大於20的數據 10 //lambda表達式 11 //var c =a.Where(p=>{return p > 20;}); 12 //化簡后 var可以接受任何類型 13 var c =a.Where(p=> p > 20); 14 //Where 返回類型是IEnumerable 15 //IEnumerable<int> c =a.Where(p=> p > 20); 16 foreach(int i in c) 17 { 18 Console.WriteLine(i); 19 } 20 21 } 22 }
上面可以算作小的linq查詢,但能算真正的linq,我暫時理解為廣義的linq。 例子中(p=> p > 20)其實就是個lambda表達式,是微軟定義好的一個委托,從這個委托的特點我們知道它有一個參數,返回值是bool類型。數組肯定實現了IEnumerable接口,而Where是IEnumerable<(Of <(T>)>) 成員 的一個擴展方法,MSDN中定義為 Where(Func<(Of <(UMP, Boolean>)>)) 基於謂詞篩選值序列。 (由 Enumerable 定義。)
public static IEnumerable<TSource> Where<TSource>(
this IEnumerable<TSource> source,
Func<TSource, bool> predicate
)
public delegate TResult Func<T, TResult>(
T arg
)
結合本例子上面兩句則可以刪減為以下兩種形式:
public delegate bool Func(T arg)
Func = p=>{return p > 10;};
p=>()p>10
p=>p>10
上面的三個lambda其實是等效的,實現的一個功能
public static IEnumerable Where(Func<TSource, bool> predicate)
linq查詢語句就是利用微軟定義好的方法,執行一定條件的查詢語句。(好像表達的不夠明白,下面再做一個例子來說明,希望能幫組大家理解):

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyLinq 5 { 6 public static void Main() 7 { 8 List<Student> list = new List<Student>(); 9 list.Add(new Student(){Age=10,Name="Jack"}); 10 list.Add(new Student(){Age=67,Name="Mack"}); 11 list.Add(new Student(){Age=23,Name="Dack"}); 12 list.Add(new Student(){Age=56,Name="Cack"}); 13 list.Add(new Student(){Age=8,Name="Eack"}); 14 list.Add(new Student(){Age=34,Name="Hack"}); 15 list.Add(new Student(){Age=18,Name="小紅"}); 16 //查詢出結合中年齡大於45的學生 17 Func<Student,bool> f = p=>p.Age>45; 18 IEnumerable<Student> result = list.Where<Student>(f); 19 foreach(Student s in result) 20 { 21 Console.WriteLine(s.Age+" "+s.Name); 22 } 23 //查詢出集合中年令小於30的,並且名字已E得學生 24 var result1 = list.Where(p=>p.Age<30 && p.Name.StartsWith("E")); 25 foreach(Student s in result1) 26 { 27 Console.WriteLine(s.Age+" "+s.Name); 28 } 29 30 } 31 32 } 33 public class Student 34 { 35 public int Age 36 { 37 get; 38 set; 39 } 40 public string Name 41 { 42 get;set; 43 } 44 }
linq查詢調用了微軟定義好的擴展方法進行查詢,下面我們插入一段擴展方法的內容,幫助理解上面linq中的Where擴展方法。
擴展方法:
通俗點說就是在不更改原來類的基礎山,為類添加方法。需要注意的是:1,擴展方法必須寫靜態類中。 2,擴展方法必須是靜態方法,雖然是靜態方法,但是這個擴張方法是為對象擴展的,只能由對象調用。它的定義是:
public static class 類名
{
public static 返回值 方法名(this 要擴展的類型 對象名[,參數列表])
{
}
}
我們來做三個擴展方法,1.為string類擴展個獲取文件類型的方法。2.為自定義的People類擴展一個看時間的方法。3.擴展一個獲取姓名的方法,下面我們一起來看看:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyExtendMethod 5 { 6 public static void Main() 7 { 8 //調用擴展方法獲取文件類型 9 string file = @"E:\FTPPUBLISH\學習資料\KindEditor\kindeditor-v4.0.3\examples\colorpicker.html"; 10 Console.WriteLine(file.GetFileType()); 11 string sss = "78.9.09.mp3"; 12 Console.WriteLine(sss.GetFileType()); 13 //調用擴展方法獲取時間 14 People pp = new People(); 15 pp.WatchTime("www"); 16 //獲取信息 17 string od = pp.GetInfo("張三"); 18 Console.WriteLine(od); 19 //為IEnumerable擴展獲取IEnumerable<int>中前十個元素的方法 20 List<int> list = new List<int>(); 21 list.Add(1); 22 list.Add(19); 23 list.Add(34); 24 list.Add(56); 25 list.Add(2); 26 list.Add(90); 27 list.Add(23); 28 list.Add(27); 29 var c = list.GetBigTen(10); 30 foreach(int d in c) 31 { 32 Console.WriteLine(d); 33 } 34 35 } 36 } 37 public static class ExtendMethod 38 { 39 /* 40 this string ss 41 這個參數只起到一個說明性作用。 42 這個擴展方法是為string的對象擴展的,只能有string的對象來使用 43 str值得是使用這個擴展方的對象。 44 */ 45 public static string GetFileType(this string str) 46 { 47 string[] strs = str.Split('.'); 48 return strs[strs.Length-1]; 49 } 50 //this People p說明這個擴展方法是為people對象擴展的,只能由People對象調用 51 public static void WatchTime(this People p,string name) 52 { 53 Console.WriteLine(name +" "+DateTime.Now); 54 } 55 public static string GetInfo(this People p,string name) 56 { 57 return name+"sssss"; 58 } 59 public static IEnumerable<int> GetBigTen(this List<int> list,int a) 60 { 61 return list.Where(p=>p>a); 62 } 63 64 } 65 public class People 66 { 67 68 }
理解了這些擴展方法,相信會有助於你理解上面linq查詢時所用的Where擴展方法。下面我們繼續來看linq查詢,把上面的linq再做一步擴展:
用linq語句進行查詢,並將結果降序分組排列的三種方法

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyLinq 5 { 6 public static void Main() 7 { 8 List<Student> list = new List<Student>(); 9 list.Add(new Student(){Age=10,Name="Jack",Address="bj"}); 10 list.Add(new Student(){Age=67,Name="Mack",Address="鄭州"}); 11 list.Add(new Student(){Age=23,Name="Dack",Address="USA"}); 12 list.Add(new Student(){Age=56,Name="Cack",Address="bj"}); 13 list.Add(new Student(){Age=8,Name="Eack",Address="鄭州"}); 14 list.Add(new Student(){Age=34,Name="Hack",Address="bj"}); 15 list.Add(new Student(){Age=18,Name="小紅",Address="USA"}); 16 //查詢出結合中年齡大於45的學生(完整的形式,一般不這樣寫) 17 Func<Student,bool> f = p=>p.Age>45; 18 IEnumerable<Student> result = list.Where<Student>(f); 19 foreach(Student s in result) 20 { 21 Console.WriteLine(s.Age+" "+s.Name); 22 } 23 //查詢出集合中年令小於30的,並按年齡降序排列,並按城市分組 24 //第一種方法 25 IEnumerable<Student> result1 = list.Where(p=>p.Age<30).OrderByDescending(p=>p.Age); 26 27 foreach(Student s in result1) 28 { 29 Console.WriteLine(s.Age + " "+s.Name); 30 } 31 IEnumerable<IGrouping<string,Student>> result2 = result1.GroupBy<Student,string>(p=>p.Address); 32 33 foreach(IGrouping<string,Student> gg in result2) 34 { 35 foreach(Student s in gg) 36 { 37 Console.WriteLine(s.Age + " "+s.Name+" "+s.Address); 38 } 39 } 40 41 42 43 44 45 /*分組的第二種方法 46 var result1 = list.Where(p=>p.Age<30).OrderByDescending(p=>p.Age).GroupBy(p=>p.Address); 47 var c = result1.GetEnumerator(); 48 while(c.MoveNext()) 49 { 50 var d = c.Current.GetEnumerator(); 51 52 while(d.MoveNext()) 53 { 54 Console.WriteLine(d.Current.Name+" "+d.Current.Address); 55 } 56 57 }*/ 58 /*分組的第三種方法 59 var result1 = list.Where(p=>p.Age<30).OrderByDescending(p=>p.Age); 60 var result2 = from p in result1 group p by p.Address; 61 foreach(Student s in result1) 62 { 63 Console.WriteLine( s.Age + " "+s.Name+" "+s.Address); 64 }*/ 65 66 } 67 68 } 69 public class Student 70 { 71 public int Age 72 { 73 get; 74 set; 75 } 76 public string Name 77 { 78 get;set; 79 } 80 public string Address 81 {get;set;} 82 }
理解了上面例子的查詢過程,你就掌握了基本的linq查詢了。仔細領會其執行順序,要理清各語句關系。
再做兩個小例子,這是我理解的完全的linq查詢:

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyLinq3 5 { 6 public static void Main() 7 { 8 9 List<Student> list = new List<Student>(); 10 list.Add(new Student(){Age=10,Name="Jack",Address="bj"}); 11 list.Add(new Student(){Age=67,Name="Mack",Address="鄭州"}); 12 list.Add(new Student(){Age=23,Name="Dack",Address="USA"}); 13 list.Add(new Student(){Age=56,Name="Cack",Address="bj"}); 14 list.Add(new Student(){Age=8,Name="Eack",Address="鄭州"}); 15 list.Add(new Student(){Age=34,Name="Hack",Address="bj"}); 16 list.Add(new Student(){Age=18,Name="小紅",Address="USA"}); 17 IEnumerable<IGrouping<string,Student>> result = from p in list 18 where p.Age > 30 19 orderby p.Age ascending 20 group p by p.Address; 21 // select p; 22 foreach(IGrouping<string,Student> s in result) 23 { 24 foreach(Student ss in s) 25 { 26 Console.WriteLine(ss.Age +" "+ss.Address); 27 } 28 } 29 30 /*用前面講到的擴展方法來查詢長度大於三的元素 31 string[] str = {"a","bb","abc","中華民謠","USA"}; 32 33 IEnumerable<string> result = from p in str 34 where p.Length>3 35 select p; 36 foreach(string s in result) 37 { 38 Console.WriteLine(s); 39 } 40 41 42 IEnumerable<string> result = str.Where<string>(p=>p.Length>3); 43 foreach(string s in result) 44 { 45 Console.WriteLine(s); 46 }*/ 47 } 48 } 49 50 public class Student 51 { 52 public int Age 53 { 54 get; 55 set; 56 } 57 public string Name 58 { 59 get;set; 60 } 61 public string Address 62 {get;set;} 63 }

1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 public class StudyLinq3 5 { 6 public static void Main() 7 { 8 9 List<Student> list = new List<Student>(); 10 list.Add(new Student(){Age=10,Name="Jack",Address="bj"}); 11 list.Add(new Student(){Age=67,Name="Mack",Address="鄭州"}); 12 list.Add(new Student(){Age=23,Name="Dack",Address="USA"}); 13 list.Add(new Student(){Age=56,Name="Cack",Address="bj"}); 14 list.Add(new Student(){Age=8,Name="Eack",Address="鄭州"}); 15 list.Add(new Student(){Age=34,Name="Hack",Address="bj"}); 16 list.Add(new Student(){Age=18,Name="小紅",Address="USA"}); 17 var result = ( from p in list 18 where p.Age >30 19 select p).OrderByDescending(pp=>pp.Age); 20 21 foreach(Student s in result) 22 { 23 Console.WriteLine(s.Age); 24 } 25 26 } 27 } 28 29 public class Student 30 { 31 public int Age 32 { 33 get; 34 set; 35 } 36 public string Name 37 { 38 get;set; 39 } 40 public string Address 41 {get;set;} 42 }
最后我們做個小小的linq總結:Linq語言集成化查詢基礎是泛型和lambda表達式他的形式是:
from 元素 in 集合
where 元素條件
orderby 元素.屬性 ascending
group 元素 by 元素.屬性
select 元素
和SQL查詢很類似,上面例子中以表明如果使用group by語句,則不需要select。
非常感謝大家騰出寶貴時間來閱讀本節,本節的講解很凌亂,如果有表達不明確之處,希望咱們私下能認真交流,共同學習。新手上路,大家多多關照…………