zoukankan      html  css  js  c++  java
  • 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

      

  • 相关阅读:
    Mac国内源安装brew
    linux基础命令(二)
    运维查看命令
    初识数据库
    镜像/容器相关操作
    docker基本命令
    Docker简介及部署
    CF1599A Weights 构造
    CSP-S 2021 游记
    GeOP 1.0开发成!
  • 原文地址:https://www.cnblogs.com/yangmengke2018/p/10922329.html
Copyright © 2011-2022 走看看