翼度科技»论坛 编程开发 .net 查看内容

Csharp学习Linq

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
Linq的学习

这里继续使用之前文章创建的学生类,首先简单介绍一下linq的使用。
Student.cs
  1. public class Student
  2. {
  3.      public int Id { get; set; }
  4.      public int ClassId { get; set; }
  5.      public string Name { get; set; }
  6.      public int Age { get; set; }
  7.      public string Description { get; set; }
  8.      public void Study()
  9.      {
  10.          Console.WriteLine($"{this.Id} {this.Name} 跟着老师学习 .Net开发");
  11.      }
  12.      public void StudyQt()
  13.      {
  14.          Console.WriteLine($"{this.Id} {this.Name} 跟着老师学习C++ Qt");
  15.      }
  16. }
复制代码
初始化学生数据
  1. public class LinqPrinciple
  2. {
  3.     private List<Student> GetStudentsList()
  4.     {
  5.         List<Student> students = new List<Student>()
  6.         { new Student() { Id = 1, ClassId = 1, Name = "张三", Age = 20, Description = "张三是一个好学生" },
  7.              new Student() { Id = 2, ClassId = 1, Name = "李四", Age = 21, Description = "李四是一个好学生" },
  8.              new Student() { Id = 3, ClassId = 2, Name = "王五", Age = 22, Description = "王五是一个好学生" },
  9.              new Student() { Id = 4, ClassId = 2, Name = "赵六", Age = 23, Description = "赵六是一个好学生" },
  10.              new Student() { Id = 5, ClassId = 3, Name = "孙七", Age = 24, Description = "孙七是一个好学生" },
  11.              new Student() { Id = 6, ClassId = 3, Name = "周八", Age = 25, Description = "周八是一个好学生" },
  12.               new Student() { Id = 7, ClassId = 1, Name = "绿春", Age = 30, Description = "张三是一个好学生" },
  13.              new Student() { Id = 8, ClassId = 1, Name = "麻醉", Age = 35, Description = "李四是一个好学生" },
  14.              new Student() { Id = 9, ClassId = 2, Name = "开天", Age = 26, Description = "王五是一个好学生" },
  15.              new Student() { Id = 10, ClassId = 2, Name = "匹敌", Age = 22, Description = "赵六是一个好学生" },
  16.              new Student() { Id = 11, ClassId = 3, Name = "独轮车", Age = 23, Description = "孙七是一个好学生" },
  17.              new Student() { Id = 12, ClassId = 3, Name = "火箭英", Age = 20, Description = "周八是一个好学生" }
  18.         };
  19.         return students;
  20.     }
  21. }
复制代码
下面写几个简单的linq的语句,大概知道一下它的使用.
  1.    public void  Show()
  2.    {
  3.        //获取一下ClassID为3的学生们
  4.        List<Student> students = GetStudentsList();
  5.        List<Student> studentsId=students.Where(s => s.ClassId == 3).ToList();
  6.        Console.WriteLine("********************************1*****************************");
  7.        foreach (var student in studentsId)
  8.        {
  9.            Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
  10.        }
  11.        Console.WriteLine("********************************2*****************************");
  12.        //获取一下年纪大于24的学生们
  13.        List<Student> studentsAge = students.Where(s => s.Age > 24).ToList();
  14.        foreach (var student in studentsAge)
  15.        {
  16.            Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
  17.        }
  18.        Console.WriteLine("********************************3*****************************");
  19.        //获取一下年纪小于23同时ClassID为2的学生们
  20.        List<Student> studentsAgeClassId = students.Where(s => s.Age < 23 && s.ClassId == 2).ToList();
  21.        foreach (var student in studentsAgeClassId)
  22.        {
  23.            Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
  24.        }
  25.    }
复制代码
linq的原理的探究

下面尝试探索一下这个linq的本质是什么?
尝试自己实现一下这3个需求代码,如下
  1. List<Student> students = GetStudentsList();
  2. List<Student> studentsId=new List<Student>();
  3. foreach (var student in students)
  4. {
  5.      if (student.ClassId == 3)
  6.      {
  7.          studentsId.Add(student);
  8.      }
  9. }
  10. List<Student> studentsAge=new List<Student>();
  11. foreach (var student in students)
  12. {
  13.      if (student.Age > 24)
  14.      {
  15.          studentsAge.Add(student);
  16.      }
  17. }
  18. List<Student> studentsAgeClassId=new List<Student>();
  19. foreach (var student in students)
  20. {
  21.      if (student.Age < 23 && student.ClassId == 2)
  22.      {
  23.          studentsAgeClassId.Add(student);
  24.      }
  25. }
复制代码
这上面的代码有什么问题?
大量的重复代码---最好是封装一些,把重复的代码统一封装;
这里使用一个解决方案
封装一个方法,将判断的逻辑独立到一个小方法中去.
  1.         public static bool  IsOk01(Student student)
  2.         {
  3.             return student.ClassId == 3;
  4.         }
  5.         public static bool IsOk02(Student student)
  6.         {
  7.             return student.Age > 24;
  8.         }
  9.         public static bool IsOk03(Student student)
  10.         {
  11.             return student.Age < 23 && student.ClassId == 2;
  12.         }
  13.         public static List<Student> DragonWhere(List<Student> studentlist,Func<Student,bool> Func)
  14.         {
  15.             List<Student> students = new List<Student>();
  16.             foreach (var student in studentlist)
  17.             {
  18.                 if (Func(student))
  19.                 {
  20.                     students.Add(student);
  21.                 }
  22.             }
  23.             return students;
  24.         }
复制代码
尝试使用一下封装的函数
  1. List<Student> students = GetStudentsList();
  2. List<Student> studentId= MethodExtension.DragonWhere(students, MethodExtension.IsOk01);
复制代码
这里还可以使用扩展方法和lambda表达式进一步的优化我们的代码
  1.       public static List<Student> DragonWhere(this List<Student> studentlist,Func<Student,bool> Func)
  2.         {
  3.             List<Student> students = new List<Student>();
  4.             foreach (var student in studentlist)
  5.             {
  6.                 if (Func(student))
  7.                 {
  8.                     students.Add(student);
  9.                 }
  10.             }
  11.             return students;
  12.         }
复制代码
在调用的时候,
  1. List<Student> students = GetStudentsList();
  2. List<Student> studentsId = students.DragonWhere(s => s.ClassId == 3);
复制代码
这里就串联上了我们之前学到的知识,最后为了支持多种数据类型,使用上泛型,最后我们就得到了最终封装的方法.
  1. public static List<T> DragonWhere<T>(this List<T> studentlist,Func<T,bool> Func)
  2. {
  3.      List<T> students = new List<T>();
  4.      foreach (var student in studentlist)
  5.      {
  6.          if (Func(student))
  7.          {
  8.              students.Add(student);
  9.          }
  10.      }
  11.      return students;
  12. }
复制代码
这里也要使用ilspy反编译一下它们的实现是如何?
看起来跟我们自己实现的Where差不多的样子.

再去看一下它的movenext函数.

这个就是一个yield return反汇编出来的状态机的代码。
linq常见的语句
  1. public void Show()
  2. {
  3.      List<Student> studentList = this.GetStudentList();
  4.      #region Linq 扩展方法&表达式
  5.      {  
  6.          var list = studentList.Where<Student>(s => s.Age < 30); //list里面必然是符合要求的数据;
  7.          foreach (var item in list)
  8.          {
  9.              Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
  10.          }
  11.      }
  12.      {
  13.          Console.WriteLine("********************");
  14.          var list = from s in studentList
  15.                     where s.Age < 30
  16.                     select s;   //list里面必然是符合要求的数据;
  17.          foreach (var item in list)
  18.          {
  19.              Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
  20.          }
  21.      }
  22.      #endregion
  23.      #region linq to object Show
  24.      {
  25.          Console.WriteLine("********************");
  26.          var list = studentList.Where<Student>(s => s.Age < 30)
  27.                               .Select(s => new  //投影:可以做一些自由组装+ new 一个匿名类,也可以new 具体类;
  28.                               {
  29.                                   IdName = s.Id + s.Name,
  30.                                   ClassName = s.ClassId == 2 ? "高级班" : "其他班"
  31.                               });
  32.          foreach (var item in list)
  33.          {
  34.              Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
  35.          }
  36.      }
  37.      {
  38.          Console.WriteLine("********************");
  39.          var list = from s in studentList
  40.                     where s.Age < 30
  41.                     select new
  42.                     {
  43.                         IdName = s.Id + s.Name,
  44.                         ClassName = s.ClassId == 2 ? "高级班" : "其他班"
  45.                     };
  46.          foreach (var item in list)
  47.          {
  48.              Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
  49.          }
  50.      }
  51.      {
  52.          Console.WriteLine("********************");
  53.          var list = studentList.Where<Student>(s => s.Age < 30)//条件过滤
  54.                               .Select(s => new//投影
  55.                               {
  56.                                   Id = s.Id,
  57.                                   ClassId = s.ClassId,
  58.                                   IdName = s.Id + s.Name,
  59.                                   ClassName = s.ClassId == 2 ? "高级班" : "其他班"
  60.                               })
  61.                               .OrderBy(s => s.Id)//排序 升序
  62.                               .ThenBy(s => s.ClassName) //多重排序,可以多个字段排序都生效
  63.                               .OrderByDescending(s => s.ClassId)//倒排
  64.                               .Skip(2)//跳过几条  //必须要先排序
  65.                               .Take(3)//获取几条 //必须要先排序
  66.                               ;
  67.          foreach (var item in list)
  68.          {
  69.              Console.WriteLine($"Name={item.ClassName}  Age={item.IdName}");
  70.          }
  71.      }
  72.      {//group by·
  73.          Console.WriteLine("********************");
  74.          var list = from s in studentList
  75.                     where s.Age < 30
  76.                     group s by s.ClassId into sg
  77.                     select new
  78.                     {
  79.                         key = sg.Key,
  80.                         maxAge = sg.Max(t => t.Age)
  81.                     };
  82.          foreach (var item in list)
  83.          {
  84.              Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
  85.          }
  86.          //group by new {s.ClassId,s.Age}
  87.          //group by new {A=s.ClassId>1}
  88.      }
  89.      {
  90.          Console.WriteLine("********************");
  91.          var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
  92.          {
  93.              key = sg.Key,
  94.              maxAge = sg.Max(t => t.Age)
  95.          });
  96.          foreach (var item in list)
  97.          {
  98.              Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
  99.          }
  100.      }
  101.      {
  102.          var list = studentList.GroupBy(s => s.ClassId);
  103.          foreach (var date in list) ///实现了IEnumerable
  104.          {
  105.              Console.WriteLine(date.Key);
  106.              foreach (var item in date)
  107.              {
  108.                  Console.WriteLine(item.Age);
  109.              }
  110.          }
  111.      }
  112.      List<Class> classList = new List<Class>()
  113.          {
  114.              new Class()
  115.              {
  116.                  Id=1,
  117.                  ClassName="架构班"
  118.              },
  119.              new Class()
  120.              {
  121.                  Id=2,
  122.                  ClassName="高级班"
  123.              },
  124.              new Class()
  125.              {
  126.                  Id=3,
  127.                  ClassName="全栈班"
  128.              },
  129.          };
  130.      {
  131.          //Join
  132.          var list = from s in studentList
  133.                     join c in classList on s.ClassId equals c.Id  //只能使用equals  不能使==
  134.                     select new
  135.                     {
  136.                         Name = s.Name,
  137.                         CalssName = c.ClassName
  138.                     };
  139.          foreach (var item in list)
  140.          {
  141.              Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
  142.          }
  143.      }
  144.      {
  145.          var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
  146.          {
  147.              Name = s.Name,
  148.              CalssName = c.ClassName
  149.          });
  150.          foreach (var item in list)
  151.          {
  152.              Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
  153.          }
  154.      }
  155.      {//左连接
  156.          var list = from s in studentList
  157.                     join c in classList on s.ClassId equals c.Id
  158.                     into scList
  159.                     from sc in scList.DefaultIfEmpty()//
  160.                     select new
  161.                     {
  162.                         Name = s.Name,
  163.                         CalssName = sc == null ? "无班级" : sc.ClassName//c变sc,为空则用
  164.                     };
  165.          foreach (var item in list)
  166.          {
  167.              Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
  168.          }
  169.          Console.WriteLine(list.Count());
  170.      }
  171.      {
  172.          var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
  173.          {
  174.              Name = s.Name,
  175.              CalssName = c.ClassName
  176.          }).DefaultIfEmpty();//为空就没有了
  177.          foreach (var item in list)
  178.          {
  179.              Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
  180.          }
  181.          Console.WriteLine(list.Count());
  182.      }
  183.      {
  184.          //左连接和右链接  就是链接对象交换一下即可;
  185.      }
  186.      #endregion
  187. }
复制代码
来源:https://www.cnblogs.com/wenlong-4613615/p/18073134
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具