zoukankan      html  css  js  c++  java
  • LINQ学习(扩展方法,委托,Lambda表达式) 第二篇

    1. LINQ基本查询操作符-获取数据

    (1) select()  语法是:

    public static IEnumerable<TResult> select<TSource,TResult>(

       this IEnumerbale<TSource> source.

    Func<TSource,TResult> selector)

    说明:1) select方法本身是一个泛型扩展方法

     2) 它作用于IEnumerable<TSource>类型

     3) 他只接受一个Func<TSource,TResult>类型参数

     4) Func<TSource,TResult>是一个泛型委托,位于System名字的空间下,System.Core.dll中,在这里Selector是一个提取器。

     (2) 举例说明,先定义一个静态类ExtraClass,然后再静态类中在定义一个静态的扩展方法,实现输出信息。代码如下:

    public static class ExtraClass

        {

            //为IEnumerable提供输出的方法

            public static void Print(this IEnumerable<string> ie)

            {

                IEnumerator<string> result = ie.GetEnumerator();

                while (result.MoveNext())

                {

                    MessageBox.Show(result.Current);

                }

            }

    }

    然后如图所示,单击图上的按钮事件,在按钮事件中的代码是:

     

    此事件下面的代码实现了将一个泛型集合中的数据循环显示出来,代码如下:

    List<string> persons = new List<string>();

        persons.Add("zhang san");

        persons.Add("zhang san feng");

        persons.Add("li si");

        persons.Add("wang wu");

        persons.Add("wang liu");

        persons.Add("li ba");

        persons.Add("lao wu");

        persons.Add("zhang xx");

        //输出persons里面的所有的元素

        var result = persons.Select(p => p);

    result.Print();

    执行结果是按顺序循环输出。

    2. LINQ基本查询操作符-过滤数据

    (1) where() 语法是:

      public static IEnumerable<TSource> where<TSource>(

          this IEnumerable<TSource> source,

    Func<TSource,bool> predicate)

    说明:1) where方法是一个泛型扩展方法

     2) 它和select()一样作用与IEnumerable<TSource>类型

     3) 它只接受一个Func<TSource,bool>泛型委托参数,在这里predicate是一个判断条件。

    (2) 举例说明,还是上面的例子,使用那个泛型集合,实现按照一定的条件输出信息。先创建一个方法,实现输出姓“zhang”的人的信息,代码如下:

    public bool Judge(string s)

            {

                if (s.StartsWith("zhang"))

                {

                    return true;

                }

                return false;

            }

      在select控件的事件下面用LINQ代码输出只是姓张的各种各样的实现代码:

    //输出persons里面姓“zhang”的人

         //var result = persons.Where(p => p.StartsWith("zhang"));  //第一种方法

         //var result = persons.Select(p => p).Where(p => p.StartsWith("zhang")); //第二种方法

         //var result = persons.Where(p => p.StartsWith("zhang")).Select(p => p);  //第三种方法

         var result = persons.Where(p => Judge(p));   //第四种方法

         result.Print();

    3. LINQ基本查询操作符-排序数据

    (1) OrderBy()  语法是:

      pblic static IOrderedEnumerable<TSource> orderBy<TSource,TKey>(

            this IEnumerable<TSource> source

           Func<TSource,TKey> keySelector)

    注:1) orderBy方法也是一个泛型扩展方法

     2) 它和select()一样作用与IEnumerable<TSource>类型

     3) 它只接收一个Func<TSource,Tkey>类型参数,在这里keySelctor指定要排序的字段。

     4) 如果想要降序排列可以使用orderbyDescending方法。

    (2) 举例说明,同上例,实现排序的代码如下:

    //var result = persons.OrderBy(p => p);

           //按照名字的最后一个字母排序

           //var result = persons.OrderBy(p => p.Substring(p.Length - 1, 1)).Select(p => p);

           //降序排列

           var result = persons.OrderByDescending(p => p);

           result.Print();

    1. Linq基本查询操作符-分组数据

    (1) GroupBy()  语法是:

       public static IEnumerable<IGrouping<Tkey,TSource>>

                   GroupBy<TSource,TKey>(

                          this IEnumerable<TSource> source,

                          Func<TSource,TKey> keySelector  )

    说明:1) GroupBy()方式和OrderBy()方式非常类似,它也是一个泛型扩展方法。

    2) 它和OrderBy()一样作用与IEnumerable<TSource>类型。

    3) 它只接受一个Func<TSource,TKey>类型参数,在这里keySelector指定要分组的字段。

    (2) 举例说明,同上例,实现分组的代码是:

    //分组---按照姓名来分组¦--取出姓名中的空格前的部分

         var result = persons.GroupBy(p => p.Split(new char[] { ' ' })[0]);

        foreach (var group in result)

        {

             Console.WriteLine("姓:" + group.Key);

             foreach (var name in group)

              {

                   Console.WriteLine("\t" + name);

              }

              Console.WriteLine();

         }

    1. 查询执行的时机

    (1) 从前面的试验中,我们发现一次查询实际上经过以下3步。

     1) 第一步:获取数据源  int[] numbers=new int[]{3,45,65,76,2,434,54,65,76,76,65,43};

      2) 第二步:定义查询  var even=numbers.Where(p=>p%2==0).Select(p=>{

    Console.WriteLine(“Hi!”+p.ToString());

    return p;     });

      3) 第三步:执行查询   foreach(var item in even){   }

    1. 查询执行的时机小节

    (1) 查询分为以下三步,获取数据源,定义查询,执行查询

    (2) 定义查询后,查询直到需要枚举结果时才被真正执行,这种方法称为”延迟执行”。

    (3) 当查询结果返回单一值时,查询立即执行。举例,如代码:

             //查询时机---当返回值为单值时马上执行语句,负责延迟执行

          var result = persons.Select(p => p).Count();

          Console.WriteLine("个数是" + result);

    (4) 因此,可以通过以下技巧在定义查询时就强制执行查询

    1. Linq查询的两种方式

    (1) Method syntax,查询方法方式

      主要利用System.Linq.Enumerable类中定义的扩展方法和Lambda表达式方式进行查询。

    (2) Query syntax ,查询语句方式

    1. 查询语句VS查询方法

    注:查询语句和查询方法存在着紧密的关系

    (1) CLR本身并不理解查询语句,它只理解查询方法。

    (2) 编译器负责在编译时将查询语句翻译为查询方法。

    (3) 大部分查询方法都有对应的查询语句形式,如:Select()对应select,OrderBy()对应orderby。

    (4)部分查询方法目前在C#中还没有对应的查询语句:如:Count()和Max()这时只能采用以下替代方案

      1) 查询方法

      2) 查询语句+查询方法的混合方式

    (5) 一般情况下,建议使用可读性更好的查询语句。举例说明:

    还是用上面多定义的泛型集合数组persons,用查询语句实现几个简单的功能,代码如下:

    //输出persons中的所有的元素

    var result = from p in persons select p;

        //输出persons中姓zhang的人----语句和方法的混合编排?

         var result = (from p in persons select p).Where(p => p.StartsWith("zhang"));

         //排序

          var result = from p in persons orderby p select p;

          result.Print();

    1. 高级查询方法

    (1) 聚合类  Count(),Max()/Min(),Average(),Sum()。举例说明:

     重新定义一个数组来实现上面的各种各样的方法,代码如下:

       //LINQ to Objects查询高级方法

          //数组数据arr

          int[] arr = { 23, 34, 5, 5, 23, 45, 65, 33, 43, 76, 67, 87 };

          //聚合类

          Console.WriteLine("arr的最大值: + arr.Max());

          Console.WriteLine("arr的最小值¦: " + arr.Min());

          Console.WriteLine("arr的平均值¦: " + arr.Average());

          Console.WriteLine("arr的数组元素个是" + arr.Count());

          Console.WriteLine("arr的总和是: " + arr.Sum());

    (2) 排序类  thenBy()  代码如下:

          //排序类

          var result = arr.OrderBy(p => p.ToString().Substring(0, 1));

          //2次排序混编模式没有达到要求

          var result = arr.OrderBy(p => p.ToString().Substring(0, 1)).ThenBy(p => p);

          //按照语句排序

          var t = arr.OrderBy(p => p.ToString().Substring(0, 1));

          var result = from p in t orderby p descending select p;

    (3) 分区类  Take,TakeWhile,Skip,SkipWhile   代码如下:

          //分区类

          var result = arr.Skip(3).Take(3);  //跳过三个值取三个值

          var result = arr.Skip(3);  //跳过几个值

    var result = arr.SkipWhile(p => p > 4); //方法体部分是该Linq语句不在往后执行的条件,当第一次遇到条件成立时,取剩下的所有元素

          var result = arr.TakeWhile(p => p > 4); //方法体部分是该Linq语句提取数据的条件,当第一次遇到条件不成立的情况就停止执行

    (4) 集合类   Distinct   代码如下:

          //集合类

          var result = arr.Distinct();

    (5) 生成类   Range,Repeat   代码如下:

          //生成类-----静态类

           var result = System.Linq.Enumerable.Range(10, 50);

           var result = System.Linq.Enumerable.Range('a', 50); //生成连续的序列

           var result = System.Linq.Enumerable.Repeat(40, 10);

           result.Print();

    1. 生成类查询方法小结

    注:使用生成类查询方法时,需要注意以下几点:

    (1) 和其它几类方法不同,Range/Repeat不是扩展方法,而是普通的静态方法

    (2) Range只能产生整数序列。

    (3) Repeat可以产生泛型序列。

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

  • 相关阅读:
    Linux安装MySQL5.7
    Linux安装MySQL5.7
    人工智能与VR结合:带来体验多样性
    人工智能与VR结合:带来体验多样性
    人工智能与VR结合:带来体验多样性
    人工智能与VR结合:带来体验多样性
    全栈必备Log日志
    全栈必备Log日志
    没想到,我们的分布式缓存竟这样把注册中心搞垮!
    Python爬虫入门教程 47-100 mitmproxy安装与安卓模拟器的配合使用-手机APP爬虫部分
  • 原文地址:https://www.cnblogs.com/hanyinglong/p/2505431.html
Copyright © 2011-2022 走看看