var、扩展方法、简单委托、匿名方法、Lambda、LINQ

1.var推断类型

  只能定义局部变量,不能定义成员变量

  定义的时候必须同时完成初始化,不能使用var定义变量为null

  var本身不是一个新类型,只是用来修饰可以推断出具体类型的局部变量

  从IL编译的角度来讲,没有任何区别

2.匿名类

  直接使用new关键字创建对象,使用var定义对象属性

  而不需要提前编写类的成员,并且只能添加对象的属性

1 var objPerson=new
2 {
3    Name="小王",
4    Age=25,
5    ClassName="软件1班"  
6 };
匿名内

3.扩展方法

  扩展方法必须在静态类中定义

  扩展方法是静态方法

  类本身的方法与扩展方法重名时,类本身的方法被优先使用

  第一个参数前加关键字this,this后的类型表示为所有的此种类型添加扩展方法4

  扩展方法内如果只有一个参数,它不是参数,代表当前变量

  扩展方法也可以重载

  扩展方法不要过多使用

4.扩展方法的应用

  如果想为一个封装好的密封类添加一个方法,可以用扩展方法

5.扩展方法的定义

  不带参数的扩展方法:  static 方法名 (this 目标类型 目标类型参数)

  带参数的扩展方法定义:   static 方法名 (this 目标类型 目标类型参数, 参数类型1 参数名1,,...... )

 1 public static int GetAvg(this int sum)
 2 {
 3       return sum / 5;
 4 }
 5 
 6 public static string StuInfo(this string name)
 7 {
 8       return string.Format("{0}你好,你的5门平均成绩为:", name);
 9 }
10 
11 public static string WelcomeStu(this Student stu)
12 {
13       return "欢迎你:" + stu.StuName;
14 }
15 
16 public static string WelcomeStu(this Student stu,int age)
17 {
18       return string.Format("姓名{0},年龄{1}", stu.StuName,age);
19 }
扩展方法

 6.委托

  委托可以看成是一种数据类型,可用于定义变量,但它是一种特殊的变量。

  委托定义的变量能接受的数值只能是一个方法(函数),可以理解委托就是一个方法的指针。

7.委托使用的步骤

  7.1声明委托,一般声明在类的外部

  7.2根据委托定义的函数原型编写需要的方法(可能多个方法)

  7.3实例化委托对象,委托在使用前必须实例化,实例化时需指定一个默认的方法

  7.4通过委托调用方法,而不是直接调用方法

  7.5委托对象所关联的方法可以动态变化(+=、-=)

 1 //【1】声明委托(定义一个函数的原型:返回值 + 参数类型和个数)
 2 //一般定义在类的外部
 3 public delegate int CalculatorDelegate(int a, int b);
 4 //【2】根据委托定义一个“具体方法”实现加法功能
 5 static int Add(int a, int b)
 6 {
 7      return a + b;
 8 }
 9 //【2】根据委托定义一个“具体方法”实现减法功能
10 static int Sub(int a, int b)
11 {
12      return a - b;
13 }
14 static void Main(string[] args)
15 {
16       //【3】创建委托对象,关联“具体方法”
17       CalculatorDelegate objCal = new CalculatorDelegate(Add);
18       //【4】通过委托去调用方法,而不是直接使用方法
19       int result = objCal(10, 20);
20       Console.WriteLine("10+20={0}", result);
21 
22       objCal -= Add;  //断开当前委托对象所关联的方法(加法)
23       objCal += Sub; //重新指向一个新的方法(减法)
24 
25       result = objCal(10, 20); //重新使用委托对象,完成减法功能
26       Console.WriteLine("10-20={0}", result);
27       Console.ReadLine();
28 }
使用委托的5个步骤

8.匿名方法

  没有具体名称、而只有委托关键字、方法参数、方法体,所以称之为匿名方法。

 1 static void Main(string[] args)
 2 {
 3      //委托变量接收一个匿名方法
 4      CalculatorDelegate objCal = delegate(int a, int b)
 5      {
 6            return a + b;
 7       };
 8       int result = objCal(10, 20);
 9       Console.WriteLine("10+20={0}", result);
10       Console.ReadLine();
11 }
匿名方法

9.Lambda表达式

  (参数列表) => {方法体}    goes to

  参数列表中的参数类型可以是“明确”的或Var的

  如果是Var的,则参数的数据类型将由编译器根据上下文自动推断出来

 1 static void Main(string[] args)
 2 {
 3      //委托变量接收一个Lambda表达式
 4      CalculatorDelegate objCal = (int a, int b) => { return a + b; };
 5      int result = objCal(10, 20);
 6      Console.WriteLine("10+20={0}", result);
 7      Console.ReadLine();
 8 }
 9 
10 static void Main(string[] args)
11 {
12      MathDelegate objMath = a => a * a;
13      int result = objMath(10);
14      Console.WriteLine("a的平方={0}", result);
15      Console.ReadLine();
16 }
Lambda表达式

  如果参数只有一个可以省略();如果方法体只有一行代码可以省略{}

10.LINQ,语言集成查询

  10.1 LINQ to Objects 主要负责对象的查询

  10.2 LINQ to XML 主要负责XML的查询

  10.3 LINQ to ADO.NET 主要负责数据库的查

      10.3.1 LINQ to SQL :目前已没人使用

      10.3.2 LINQ to DataSet :应用一般

      10.3.3 LINQ to Entiies : 重点学习

 1 static void Main(string[] args)
 2 {
 3      int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4      List<int> list = new List<int>();
 5      foreach (int item in nums)
 6      {
 7           if (item % 2 != 0)
 8                list.Add(item);
 9      }
10      list.Sort();
11      list.Reverse();
12      foreach (int item in list)
13      {
14            Console.WriteLine(item);
15      }
16      Console.ReadLine();
17 }
不使用LINQ查询数组
 1 static void Main(string[] args)
 2 {
 3       int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4 
 5       //查询数组中的奇数并按降序排列输出
 6       var list = from num in nums
 7                     where num % 2 != 0
 8                     orderby num descending
 9                     select num;
10 
11       foreach (int item in list)
12       {
13            Console.WriteLine(item);
14       }
15       Console.ReadLine();
16 }
使用LINQ查询

11.LINQ中的Select()方法

  Select()是一个泛型扩展方法

  Select()方法使用的时候,要求传递一个委托实例

  数组、泛型集合都可以使用扩展方法Select()

 1 static void Main(string[] args)
 2 {
 3       int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4 
 5       //返回数组中每个数值的平方
 6       //Select()方法里面是一个Lambda表达式
 7       //返回结果是一个迭代器(Iterator)
 8       var list = nums.Select(item => item * item);
 9       foreach (int item in list)
10       {
11             Console.WriteLine(item);
12       }
13 
14       Console.ReadLine();
15 }
扩展方法Select()应用

  迭代器就是一个类似于数组和泛型集合可以遍历的东西

12.LINQ中的Where()方法

  Where()方法是一个泛型扩展方法

  Where()方法使用的时候要求传递一个委托实例,该实例是一个判断条件,返回的类型必须是bool类型

 1 static void Main(string[] args)
 2 {
 3       int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4 
 5       //先对数组内的数值进行判断,保留偶数
 6       //对是偶数的源数据进行平方
 7       var list = nums
 8                      .Where(item => item % 2 == 0)
 9                      .Select(i => i * i);
10 
11       Console.ReadLine();
12 }
扩展方法Where()应用

13.LINQ中的OrderBy()方法

  OrderBy()方法是一个泛型扩展方法

  OrderBy()里面的参数要求传递一个排序的字段,如果字段是int,参数可以是(item=>item),如果想按照字符串的首字母排序可以是(item=>item.Substring(0,1))

       升序排列(从小到大)可以用OrderBy()方法

  降序排列(从大到小)可以用OrderByDescending()方法

 1 static void Main(string[] args)
 2 {
 3       int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4 
 5       //1.先提取偶数
 6       //2.对是偶数的进行平凡
 7       //3.对平凡后的数值进行排序(升序)    
 8       var list = nums
 9                      .Where(item => item % 2 == 0)
10                      .Select(i => i * i)
11                      .OrderBy(item => item);
12       foreach (int i in list)
13       {
14             Console.WriteLine(i);
15       }
16 
17       Console.ReadLine();
18 }
扩展方法OrderBy()升序应用
 1 static void Main(string[] args)
 2 {
 3      string[] nums = { "张勇", "王琦", "刘静", "赵鑫鑫",
 4                                 "杜丽", "马俊才", "那英", "成龙", };
 5 
 6       //1.先提取出名字是两个字的
 7       //2.按名字首字母进行降序(Z—>A)排列
 8       var list = nums
 9                      .Where(item => item.Length == 2)
10                      .Select(item => item)
11                      .OrderByDescending(item => item.Substring(0, 1));
12       foreach (string item in list)
13       {
14            Console.WriteLine(item);
15       }
16 
17       Console.ReadLine();
18 }
扩展方法OrderByDescending()降序应用

14.LINQ中的GroupBy()方法

       GroupBy()方法是一个泛型扩展方法

  GroupBy()里面的参数要求传递一个f分组的字段

 1 static void Main(string[] args)
 2 {
 3      string[] nums = { "张勇", "王琦", "刘静", "赵鑫鑫","杜丽", 
 4 "马俊才", "那英", "成龙","王丽", "杜宇","马晓","刘丽","马大哈",};
 5 
 6      //1.先提取两个字的名字
 7      //2.按姓进行分组
 8      var list = nums
 9                 .Where(item => item.Length == 2)
10                 .Select(item => item)
11                 .GroupBy(item => item.Substring(0, 1));
12 
13       foreach (var groupItem in list)
14      {
15            Console.WriteLine("-------------------");
16            Console.WriteLine("分组字段:{0}", groupItem.Key);
17 
18            foreach (var item in groupItem)
19            {
20                Console.WriteLine(item);
21            }
22      }
23      Console.ReadLine();
24 }
扩展方法GroupBy()应用

 15.LINQ查询的时机:延迟执行

   定义查询后,查询并没有立即执行,而是直到需要枚举结果(遍历)时才真正被执行

   顺序:获取数据源、定义查询、执行查询(不使用不执行)

16.Count()方法

  使用“聚合扩展方法”返回单一结果,强制查询立即执行。后加.Count(),查询定义后会立即执行

 17.LINQ查询的两种形式:查询语句、查询方法

  查询语句比较接近于SQL语句查询,可读性更好,但查询语句最后还是要被翻译成查询方法。

  查询方法利用System.Linq.Enumerble类中的扩展方法和Lambda表达式进行查询。

 1 static void Main(string[] args)
 2 {
 3       int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
 4 
 5       var list = nums
 6              .Where(item => item % 2 == 0)
 7              .Select(i => i * i)
 8              .OrderByDescending(i => i);
 9 
10       foreach (var item in list)
11       {
12             Console.WriteLine(item);
13       }
14 
15       Console.ReadLine();
16 }
17 
18 //两者的执行效果完全一样
19 
20 static void Main(string[] args)
21 {
22        int[] nums = { 1, 7, 2, 6, 5, 4, 9, 13, 20 };
23 
24        var list = from num in nums
25                     where num % 2 == 0
26                     orderby num descending
27                     select num * num;
28 
29        foreach (var item in list)
30       {
31            Console.WriteLine(item);
32       }
33 
34        Console.ReadLine();
35 }
查询语句VS查询方法

  我个人觉得直接用查询方法好一些,可以多多使用Lambda表达式。

   个人杂记:最近每次遇到“求”字,内心都起波澜,想起中学一篇文章叫《送东阳马生序》,是文人宋濂讲述自己年少求学时的经历。细想人这一生,年少求学,毕业求职,成年求偶,婚后求子,中年求财,老年求后,真可谓不得不积极入世,一心相求。其中经历虽若坎坷艰难,但仔细思考,人生就是因为追求而精彩,生命正是因为拼搏而有意义,每一次的追求与拼搏都是跨过人生的一道道坎,过去了方能精彩无限,犹如登上山峦一览众山小的壮阔,仿佛临海朝平两岸阔的凯旋。

 18.LINQ查询子句

  查询表达式

    是一种查询语法表示的表达式,由一组类似于SQL的语法编写的句子组成

    每一个子句可以包含一个或多个C#表达式

    LINQ查询表达式必须以from子句开头,并且必须以select或group子句结束,中间可以添加别的子句

  LINQ查询表达式包含的子句

    from子句:指定查询操作的数据源和范围变量

    where子句:筛选元素的逻辑条件,返回值是一个bool类型

    select子句:指定查询结果的类型和变现形式

    orderby子句:对查询结果进行排序(升序或降序)

    group子句:对查询结果进行分组

    into子句:提供一个临时标识符,该表示可充当join/group/select子句结果的引用

    join子句:连接多个查询操作的数据源

    let子句:引入用于存储查询表达式中的子表达式的范围变量

 19.from子句

  LINQ查询表达式必须包含from子句,并且必须以from子句开头

  from子句指定的数据源必须为IEnumerable、Ienumerable<T>或者两者的派生类型(例如:数组、List<T>、ArrayList等)

  from num in nums :num表示范围变量:一般表示数据源中的每一个元素

            nums表示数据源

 20.复合from子句查询

  如果数据源的元素还包括字数据源,如果要查询字数据源中的元素,则需要使用复合from子句。

 1 static void Main(string[] args)
 2         {
 3             Student obj1 = new Student()
 4             {
 5                 StuId = 1001, StuName = "学员1", ScoreList = new List<int>() { 90, 78, 54 }
 6             };
 7             Student obj2 = new Student()
 8             {
 9                 StuId = 1002, StuName = "学员2", ScoreList = new List<int>() { 95, 88, 90 }
10             };
11             Student obj3 = new Student()
12             {
13                 StuId = 1003, StuName = "学员3", ScoreList = new List<int>() { 79, 76, 89 }
14             };
15             //将学员封装到集合中
16             List<Student> stuList = new List<Student>() { obj1, obj2, obj3 };
17             //查询成绩包含95分以上的学员
18             var result = from stu in stuList
19                          from score in stu.ScoreList
20                          where score >= 95
21                          select stu;
22             //显示查询结果
23             foreach (var item in result)
24             {
25                 Console.WriteLine(item.StuName);
26             }
27             Console.ReadLine();
28         }
复合from子句:查询学生成绩超过95分的学生姓名

 21.多个from子句查询

  若LINQ查询表达式包含两个或两个以上的独立数据源时,可以使用多个from子句查询所有数据源中的数据

 1 static void Main(string[] args)
 2 {
 3      Student obj1 = new Student() { StuId = 1001, StuName = "学员1" };
 4      Student obj2 = new Student() { StuId = 1009, StuName = "学员9" };
 5      Student obj3 = new Student() { StuId = 1012, StuName = "学员12" };
 6      Student obj4 = new Student() { StuId = 1003, StuName = "学员3" };
 7      Student obj5 = new Student() { StuId = 1019, StuName = "学员19" };
 8      Student obj6 = new Student() { StuId = 1006, StuName = "学员6" };
 9 
10      List<Student> stuList1 = new List<Student>() { obj1, obj2, obj3 };
11      List<Student> stuList2 = new List<Student>() { obj4, obj5, obj6 };
12 
13      //查询学好大于1010的学员
14      var result = from stu1 in stuList1
15                     where stu1.StuId >= 1010
16                     from stu2 in stuList2
17                     where stu2.StuId >= 1010
18                     elect new { stu1, stu2 };
19       //显示查询结果
20       foreach (var item in result)
21       {
22            Console.WriteLine(item.stu1.StuName + "   " + item.stu1.StuId);
23            Console.WriteLine(item.stu2.StuName + "   " + item.stu2.StuId);
24       }
25      Console.ReadLine();
26 }
多个from子句:查询两个数据源结果放在一起

22.其他常用子句

  where子句

    用于指定筛选元素的逻辑条件

    一个查询表达式可以不包含where子句

    如果查询表达式包含where子句,则where子句不能放在最后一个子句

  select子句

    用于指定查询结果的类型和表现形式

    LINQ查询表达式或以select子句结尾或以group子句结尾

  group子句

    用于对查询结果分组

    返回元素类型为Igrouping<Tkey,Telement>对象序列

  orderby子句

    用于对查询结果排序,默认“升序”

    在排序字段后加上descending可以表示降序

23.高级查询方法

  聚合类:Count  Max/Min  Average

  排序类:ThenBy

  分区类:Take  TakeWhile  Skip  SkipWhile

  集合类:Distinct

  生成类:Range  Repeat

24.Count 返回集合项的数目

   Max/Min  Average 最大最小及平均

 1 static void Main(string[] args)
 2 {
 3      Student obj1 = new Student() { StuId = 1001, StuName = "学员1" };
 4      Student obj2 = new Student() { StuId = 1009, StuName = "学员9" };
 5      Student obj3 = new Student() { StuId = 1012, StuName = "学员12" };
 6      Student obj4 = new Student() { StuId = 1003, StuName = "学员3" };
 7      Student obj5 = new Student() { StuId = 1019, StuName = "学员19" };
 8      Student obj6 = new Student() { StuId = 1006, StuName = "学员6" };
 9      List<Student> stuList = new List<Student>() { obj1, obj2, obj3, obj4, obj5, obj6 };
10 
11       var count1 = (from c in stuList
12                      where c.StuId > 1010
13                      select c).Count();
14        var count2 = stuList.Where(c => c.StuId > 1010).Count();
15        Console.WriteLine("count1={0}  count2={1}", count1, count2);
16        Console.ReadLine();
17 }
聚合函数Count
 1 static void Main(string[] args)
 2 {
 3      Student obj1 = new Student() { StuId = 1001, Age = 22, StuName = "学员1" };
 4      Student obj2 = new Student() { StuId = 1009, Age = 21, StuName = "学员9" };
 5      Student obj3 = new Student() { StuId = 1012, Age = 25, StuName = "学员12" };
 6      Student obj4 = new Student() { StuId = 1003, Age = 23, StuName = "学员3" };
 7      Student obj5 = new Student() { StuId = 1019, Age = 27, StuName = "学员19" };
 8      Student obj6 = new Student() { StuId = 1006, Age = 24, StuName = "学员6" };
 9      List<Student> stuList = new List<Student>() { obj1, obj2, obj3, obj4, obj5, obj6 };
10 
11      var maxAge = (from s in stuList select s.Age).Max();
12      var minAge = stuList.Select(s => s.Age).Min();
13      var avgAge = (from s in stuList select s.Age).Average();
14      var sumAge = (from s in stuList select s.Age).Sum();
15 
16      Console.WriteLine("maxAge={0} minAge={1} avgAge={2} sumAge={3}",
17                 maxAge, minAge, avgAge, sumAge);
18 
19      Console.ReadLine();
20 }
聚合函数Max、Min、Average

25.ThenBy提供符合排序条件

 1 static void Main(string[] args)
 2 {
 3       Student obj1 = new Student() { StuId = 1001, Age = 22, StuName = "学员1" };
 4       Student obj2 = new Student() { StuId = 1009, Age = 21, StuName = "学员9" };
 5       Student obj3 = new Student() { StuId = 1012, Age = 25, StuName = "学员12" };
 6       Student obj4 = new Student() { StuId = 1003, Age = 23, StuName = "学员3" };
 7       Student obj5 = new Student() { StuId = 1019, Age = 27, StuName = "学员19" };
 8       Student obj6 = new Student() { StuId = 1006, Age = 24, StuName = "学员6" };
 9       List<Student> stuList = new List<Student>() { obj1, obj2, obj3, obj4, obj5, obj6 };
10       var stus1 = from s in stuList
11                   orderby s.StuName, s.Age, s.StuId
12                   select s;
13       var stus2 = stuList
14              .OrderBy(s => s.StuName)
15              .ThenBy(s => s.Age)
16              .ThenBy(s => s.StuId)
17              .Select(p => p);
18       foreach (var s in stus1)
19       {
20              Console.WriteLine(s.StuName);
21       }
22       Console.WriteLine("----------------------");
23       foreach (var s in stus2)
24       {
25              Console.WriteLine(s.StuName);
26       }
27       Console.ReadLine();
28 }
排序类ThenBy的使用

26.Take  提取指定数量的项

  Skip  跳过指定数量的项并获取剩余的项

  TakeWhile  只要满足指定的条件,就会返回序列的元素,然后跳过剩余的元素

  SkipWhile  只要满足指定的条件,就跳过序列中的元素,然后返回剩余元素

 1 static void Main(string[] args)
 2 {
 3      int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
 4 
 5      var list1 = nums.Skip(1);
 6      var list2 = nums.Skip(1).Take(3);
 7      var list3 = nums.SkipWhile(i => i % 3 != 0);
 8      var list4 = nums.TakeWhile(i => i % 2 != 0);
 9      var list5 = nums.SkipWhile(i => i % 3 != 0)
10                              .TakeWhile(i => i % 2 != 0);
11 
12      foreach (var item in list1) { Console.Write(item + "  "); }
13      Console.WriteLine("
---------------------");
14      foreach (var item in list2) { Console.Write(item + "  "); }
15      Console.WriteLine("
---------------------");
16      foreach (var item in list3) { Console.Write(item + "  "); }
17      Console.WriteLine("
---------------------");
18      foreach (var item in list4) { Console.Write(item + "  "); }
19      Console.WriteLine("
---------------------");
20      foreach (var item in list5) { Console.Write(item + "  "); }
21 
22      Console.ReadLine();
23 }
分区类查询

 27.Range  生成一个整数序列

   Repeat  生成一个重复项的序列

  Rang/Repeat不是扩展方法,而是普通的静态方法

  Rang只能产生证书序列

  Repeat可以产生泛型序列

  所有的查询方法都存放在System.Linq.Enumerable静态类中

 1 static void Main(string[] args)
 2 {
 3      var nums1 = Enumerable.Range(1, 10);
 4      var nums2 = Enumerable.Repeat("LINQ best!", 10);
 5 
 6      foreach (var item in nums1) { Console.WriteLine(item); }
 7      Console.WriteLine("------------");
 8      foreach (var item in nums2) { Console.WriteLine(item); }
 9 
10      Console.ReadLine();
11 }
生成类查询

28.Distinct  去除重复的元素

1 static void Main(string[] args)
2 {
3      int[] nums = { 1, 2, 2, 6, 5, 6, 7, 8, 8 };
4      var list = nums.Distinct();
5 
6      foreach (var item in list) { Console.WriteLine(item); }
7 
8      Console.ReadLine();
9 }
集合类查询Distinct

  

原文地址:https://www.cnblogs.com/yangmengke2018/p/10922329.html