朋友,或许你了解委托,熟悉监视者模式,常用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。

非常感谢大家腾出宝贵时间来阅读本节,本节的讲解很凌乱,如果有表达不明确之处,希望咱们私下能认真交流,共同学习。新手上路,大家多多关照…………

 

posted on 2012-08-11 10:08  bergy  阅读(2063)  评论(13编辑  收藏  举报