從委托、lambda表達式到linq的一些個人小總結


朋友,或許你了解委托,熟悉監視者模式,常用lambda表達式或者linq查詢,自定義過擴展方法,但假如你沒留意過他們之間的關系,不清楚委托是如何演變為lambda表達式,再如何導出linq語句的,又或者想了解以上知識內容的,那么就進來一起學習本節吧。本節我們要了解委托和監視者模式,然后再由匿名委托一步步導出lambda表達式,最后用lambda表達式結合擴展方法來舉例闡釋Linq查詢。這節是委托到Linq集成化查詢的小小推導,希望能對大家有所幫助。本人新手上路,難免紕漏重重,還望大伙兒海涵。更希望大家能提出寶貴意見,鄙人感激不盡。下面咱們就一起探討學習本節內容吧……

委托:

用Delegate 關鍵字聲明委托,下面要引用MSDN上的一段內容,它們概括出我不能解釋的隱含知識:委托是一種引用方法的類型。一旦為委托分配了方法,委托將與該方法具有完全相同的行為。委托方法的調用可以像其他任何方法一樣,具有參數和返回值。委托是一種安全地封裝方法的類型,它與 C 和 C++ 中的函數指針類似。與 C 中的函數指針不同,委托是面向對象的、類型安全的和保險的。委托的類型由委托的名稱定義。下面的示例聲明了一個名為 Del 的委托,該委托可以封裝了采用字符串作為參數並返回 void類型 的方法。public delegate void Del(string message);    下面寫個委托的例子來幫組大家理解,重點是要理解其中為什么可以把方法名賦值給委托對象。可以參考例子:int a = 0;因為等號左右同為數值類型,類型一致,所以可以賦值。

View Code
 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.

View Code
 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.

View Code
 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.

View Code
 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 }

上述委托是當做參數來傳遞的,傳遞之后就可以當做方法使用。封裝了共同方法,又傳入委托做參數來調用方法后,當添加新的成員國家,我們就不必再更改方法的主題部分,相比之上的兩個程序,它安全性、可拓展性就好很多。了解了什么是委托了,我們就要來看看什么是監視者模式。

監視者模式:

監視者模式是在微軟平台上大量存在的一種模式,通俗一點它就是事件,事件就是監視者模式。比如生活中,你睡覺的時候委托同學上課叫醒你,這就是一個監視者模式,你是被監視者,是委托方,同學是被委托方,監視者。下面給大家舉個例子:考試的時候自己委托父母監視自己,考的好的話讓父母獎勵,考差了則受罰的監視者模式:

View Code
 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代替了匿名委托的方法名,很多情況在不必要創建方法,需要臨時創建方法來調用時使用 ,下面例子能很好說明匿名委托的不同用法

View Code
 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表達式具體例子:

View Code
 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表達式不同形式的小總結:

View Code
 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語句循環輸出:

View Code
 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;

View Code
 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查詢語句就是利用微軟定義好的方法,執行一定條件的查詢語句。(好像表達的不夠明白,下面再做一個例子來說明,希望能幫組大家理解):

View Code
 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.擴展一個獲取姓名的方法,下面我們一起來看看:

View Code
 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語句進行查詢,並將結果降序分組排列的三種方法

View Code
 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查詢:

View Code
 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 }
View Code
 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。

非常感謝大家騰出寶貴時間來閱讀本節,本節的講解很凌亂,如果有表達不明確之處,希望咱們私下能認真交流,共同學習。新手上路,大家多多關照…………

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM