Csharp学习Linq

Linq的学习

这里继续使用之前文章创建的学生类,首先简单介绍一下linq的使用。

Student.cs

 public class Student
 {
     public int Id { get; set; }
     public int ClassId { get; set; }

     public string Name { get; set; }

     public int Age { get; set; }

     public string Description { get; set; }

     public void Study()
     {
         Console.WriteLine($"{this.Id} {this.Name} 跟着老师学习 .Net开发");

     }

     public void StudyQt()
     {
         Console.WriteLine($"{this.Id} {this.Name} 跟着老师学习C++ Qt");
     }
 }

初始化学生数据

public class LinqPrinciple
{
    private List<Student> GetStudentsList()
    {
        List<Student> students = new List<Student>()
        { new Student() { Id = 1, ClassId = 1, Name = "张三", Age = 20, Description = "张三是一个好学生" },
             new Student() { Id = 2, ClassId = 1, Name = "李四", Age = 21, Description = "李四是一个好学生" },
             new Student() { Id = 3, ClassId = 2, Name = "王五", Age = 22, Description = "王五是一个好学生" },
             new Student() { Id = 4, ClassId = 2, Name = "赵六", Age = 23, Description = "赵六是一个好学生" },
             new Student() { Id = 5, ClassId = 3, Name = "孙七", Age = 24, Description = "孙七是一个好学生" },
             new Student() { Id = 6, ClassId = 3, Name = "周八", Age = 25, Description = "周八是一个好学生" },
              new Student() { Id = 7, ClassId = 1, Name = "绿春", Age = 30, Description = "张三是一个好学生" },
             new Student() { Id = 8, ClassId = 1, Name = "麻醉", Age = 35, Description = "李四是一个好学生" },
             new Student() { Id = 9, ClassId = 2, Name = "开天", Age = 26, Description = "王五是一个好学生" },
             new Student() { Id = 10, ClassId = 2, Name = "匹敌", Age = 22, Description = "赵六是一个好学生" },
             new Student() { Id = 11, ClassId = 3, Name = "独轮车", Age = 23, Description = "孙七是一个好学生" },
             new Student() { Id = 12, ClassId = 3, Name = "火箭英", Age = 20, Description = "周八是一个好学生" }

        };
        return students;
    }
}

下面写几个简单的linq的语句,大概知道一下它的使用.


   public void  Show()
   {
       //获取一下ClassID为3的学生们
       List<Student> students = GetStudentsList();
       List<Student> studentsId=students.Where(s => s.ClassId == 3).ToList();
       Console.WriteLine("********************************1*****************************");
       foreach (var student in studentsId)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
       Console.WriteLine("********************************2*****************************");
       //获取一下年纪大于24的学生们
       List<Student> studentsAge = students.Where(s => s.Age > 24).ToList();
       foreach (var student in studentsAge)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
       Console.WriteLine("********************************3*****************************");
       //获取一下年纪小于23同时ClassID为2的学生们
       List<Student> studentsAgeClassId = students.Where(s => s.Age < 23 && s.ClassId == 2).ToList();
       foreach (var student in studentsAgeClassId)
       {
           Console.WriteLine($"{student.Id} {student.Name} {student.Age} {student.Description}");
       }
   }

linq的原理的探究

下面尝试探索一下这个linq的本质是什么?

尝试自己实现一下这3个需求代码,如下

 List<Student> students = GetStudentsList();
 List<Student> studentsId=new List<Student>();
 foreach (var student in students)
 {
     if (student.ClassId == 3)
     {
         studentsId.Add(student);
     }
 }

 List<Student> studentsAge=new List<Student>();
 foreach (var student in students)
 {
     if (student.Age > 24)
     {
         studentsAge.Add(student);
     }
 }

 List<Student> studentsAgeClassId=new List<Student>();
 foreach (var student in students)
 {
     if (student.Age < 23 && student.ClassId == 2)
     {
         studentsAgeClassId.Add(student);
     }
 }

这上面的代码有什么问题?

大量的重复代码---最好是封装一些,把重复的代码统一封装;

这里使用一个解决方案

封装一个方法,将判断的逻辑独立到一个小方法中去.

        public static bool  IsOk01(Student student)
        {
            return student.ClassId == 3;
        }

        public static bool IsOk02(Student student)
        {
            return student.Age > 24;
        }

        public static bool IsOk03(Student student)
        {
            return student.Age < 23 && student.ClassId == 2;
        }
        public static List<Student> DragonWhere(List<Student> studentlist,Func<Student,bool> Func)
        {
            List<Student> students = new List<Student>();
            foreach (var student in studentlist)
            {
                if (Func(student))
                {
                    students.Add(student);
                }
            }
            return students;
        }

尝试使用一下封装的函数

List<Student> students = GetStudentsList();
List<Student> studentId= MethodExtension.DragonWhere(students, MethodExtension.IsOk01);

这里还可以使用扩展方法和lambda表达式进一步的优化我们的代码

      public static List<Student> DragonWhere(this List<Student> studentlist,Func<Student,bool> Func)
        {
            List<Student> students = new List<Student>();
            foreach (var student in studentlist)
            {
                if (Func(student))
                {
                    students.Add(student);
                }
            }
            return students;
        }

在调用的时候,

List<Student> students = GetStudentsList();
List<Student> studentsId = students.DragonWhere(s => s.ClassId == 3);

这里就串联上了我们之前学到的知识,最后为了支持多种数据类型,使用上泛型,最后我们就得到了最终封装的方法.

 public static List<T> DragonWhere<T>(this List<T> studentlist,Func<T,bool> Func)
 {
     List<T> students = new List<T>();
     foreach (var student in studentlist)
     {
         if (Func(student))
         {
             students.Add(student);
         }
     }
     return students;
 }

这里也要使用ilspy反编译一下它们的实现是如何?

看起来跟我们自己实现的Where差不多的样子.

img

再去看一下它的movenext函数.

img

这个就是一个yield return反汇编出来的状态机的代码。

linq常见的语句

 public void Show()
 {
     List<Student> studentList = this.GetStudentList(); 
     #region Linq 扩展方法&表达式
     {  
         var list = studentList.Where<Student>(s => s.Age < 30); //list里面必然是符合要求的数据;
         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
         }
     }
     {
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    select s;   //list里面必然是符合要求的数据;

         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.Name, item.Age);
         }
     }
     #endregion

     #region linq to object Show
     {
         Console.WriteLine("********************");
         var list = studentList.Where<Student>(s => s.Age < 30)
                              .Select(s => new  //投影:可以做一些自由组装+ new 一个匿名类,也可以new 具体类;
                              {
                                  IdName = s.Id + s.Name,
                                  ClassName = s.ClassId == 2 ? "高级班" : "其他班"
                              });
         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
         }
     }
     {
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    select new
                    {
                        IdName = s.Id + s.Name,
                        ClassName = s.ClassId == 2 ? "高级班" : "其他班"
                    };

         foreach (var item in list)
         {
             Console.WriteLine("Name={0}  Age={1}", item.ClassName, item.IdName);
         }
     }
     {
         Console.WriteLine("********************");
         var list = studentList.Where<Student>(s => s.Age < 30)//条件过滤
                              .Select(s => new//投影
                              {
                                  Id = s.Id,
                                  ClassId = s.ClassId,
                                  IdName = s.Id + s.Name,
                                  ClassName = s.ClassId == 2 ? "高级班" : "其他班"
                              })
                              .OrderBy(s => s.Id)//排序 升序
                              .ThenBy(s => s.ClassName) //多重排序,可以多个字段排序都生效
                              .OrderByDescending(s => s.ClassId)//倒排
                              .Skip(2)//跳过几条  //必须要先排序
                              .Take(3)//获取几条 //必须要先排序
                              ;
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.ClassName}  Age={item.IdName}");
         }
     }
     {//group by·
         Console.WriteLine("********************");
         var list = from s in studentList
                    where s.Age < 30
                    group s by s.ClassId into sg
                    select new
                    {
                        key = sg.Key,
                        maxAge = sg.Max(t => t.Age)
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
         }
         //group by new {s.ClassId,s.Age}
         //group by new {A=s.ClassId>1}
     }
     {
         Console.WriteLine("********************");
         var list = studentList.GroupBy(s => s.ClassId).Select(sg => new
         {
             key = sg.Key,
             maxAge = sg.Max(t => t.Age)
         });
         foreach (var item in list)
         {
             Console.WriteLine($"key={item.key}  maxAge={item.maxAge}");
         }
     }
     {
         var list = studentList.GroupBy(s => s.ClassId);
         foreach (var date in list) ///实现了IEnumerable
         {
             Console.WriteLine(date.Key);

             foreach (var item in date)
             {
                 Console.WriteLine(item.Age);
             }

         }

     }
     List<Class> classList = new List<Class>()
         {
             new Class()
             {
                 Id=1,
                 ClassName="架构班"
             },
             new Class()
             {
                 Id=2,
                 ClassName="高级班"
             },
             new Class()
             {
                 Id=3,
                 ClassName="全栈班"
             },
         };
     {

         //Join 
         var list = from s in studentList
                    join c in classList on s.ClassId equals c.Id  //只能使用equals  不能使==
                    select new
                    {
                        Name = s.Name,
                        CalssName = c.ClassName
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
     }
     {
         var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
         {
             Name = s.Name,
             CalssName = c.ClassName
         });
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
     }
     {//左连接
         var list = from s in studentList
                    join c in classList on s.ClassId equals c.Id
                    into scList
                    from sc in scList.DefaultIfEmpty()//
                    select new
                    {
                        Name = s.Name,
                        CalssName = sc == null ? "无班级" : sc.ClassName//c变sc,为空则用
                    };
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
         Console.WriteLine(list.Count());
     }
     {
         var list = studentList.Join(classList, s => s.ClassId, c => c.Id, (s, c) => new
         {
             Name = s.Name,
             CalssName = c.ClassName
         }).DefaultIfEmpty();//为空就没有了
         foreach (var item in list)
         {
             Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
         }
         Console.WriteLine(list.Count());
     }
     {

         //左连接和右链接  就是链接对象交换一下即可;

     }
     #endregion
 }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/480272.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

欧科云链:2024将聚焦发展与安全,用技术助力链上数据安全和合规

近期&#xff0c;OpenAI和Web3.0两大新技术发展势头迅猛。OpenAI 再次引领AI领域的新浪潮&#xff0c;推出了创新的文本转视频模型——Sora&#xff0c;Sora 可以创建长达60 秒的视频&#xff0c;包含高度详细的场景、複杂的摄像机运动以及情感丰富角色&#xff0c;再次将AI 的…

网络基础「HTTP」

&#x1f52d;个人主页&#xff1a; 北 海 &#x1f6dc;所属专栏&#xff1a; Linux学习之旅、神奇的网络世界 &#x1f4bb;操作环境&#xff1a; CentOS 7.6 阿里云远程服务器 文章目录 1.再谈协议1.1.认识URL1.2.Encode 和 Decode 2.HTTP 协议2.1.协议格式2.2.见一见请求2.…

【OpenCV C++Python】(五)图像平滑(模糊)

文章目录 图像平滑均值滤波高斯滤波中值滤波双边滤波(Bilateral Filtering ) PythonC 图像线性平滑空间滤波&#xff08;加权均值滤波器&#xff0c;几何均值滤波&#xff0c;谐波均值滤波&#xff0c;逆谐波均值滤波&#xff09;&#xff0c;非线性平滑空间滤波&#xff08;中…

2024 年 5 个 Linux 开源数字化学习平台

与其他行业一样&#xff0c;教育界多年来一直在经历数字化转型的过程。随着数字化学习平台的建立&#xff0c;目前只要能上网&#xff0c;任何人都可以接受教育。 “e-learning”一词的意思是“数字化学习”&#xff0c;是当今最常用的词之一。 它指的是通常在互联网上进行的培…

unity Mirror网络同步

我们直接来剖析&#xff0c;上干货 在github上的主页代码&#xff0c;稍微修改了下&#xff1a; using System.Collections; using System.Collections.Generic; using Mirror; using UnityEngine;public class Player : NetworkBehaviour {// Synced automatically //自动同…

0201线性方程组和矩阵-矩阵及其运算-线性代数

文章目录 一、线性方程组二、矩阵的定义结语 一、线性方程组 设有 n 个未知数 m n个未知数m n个未知数m个方程的线性方程组 { a 11 x 1 a 12 x 2 ⋯ a 1 n x n b 1 , a 21 x 1 a 22 x 2 ⋯ a 2 n x n b 2 , ⋯ a m 1 x 1 a m 2 x 2 ⋯ a m n x n b m , \begin{ca…

[AutoSar]BSW_Com017 COM模块介绍(一)

目录 关键词平台说明一、COM 所处架构位置二、COM 的功能概述三、Functional Specification3.1 AUTOSAR COM basis function3.2 Signal Gateway3.2.1 Signal routing requirements3.2.2 Routing of signal groups3.2.3 Routing latency for normal Signal Gateway3.2.4 Gateway…

Nacos介绍和Eureka的区别

Nacos&#xff08;全称为 Alibaba Cloud Nacos&#xff0c;或简称为 Nacos&#xff09;是一个开源的分布式服务发现和配置管理系统。它由阿里巴巴集团开发并开源&#xff0c;旨在帮助开发人员简化微服务架构下的服务注册、发现和配置管理。 1、Nacos 提供了以下主要功能&#…

Django在日志中使用AdminEmailHandler发送邮件(同步),及celery异步发送日志邮件的实现

目录 一、使用AdminEmailHandler实现发送日志通知邮件 1&#xff0c;配置日志项 2&#xff0c;配置邮件项 3&#xff0c;在视图里使用日志 二、继承AdminEmailHandler使用celery实现异步发送邮件 1&#xff0c;安装配置celery 2&#xff0c;继承AdminEmailHandler类&…

V2X技术与智能传感器的完美融合:提升城市道路安全

在科技不断创新的今天&#xff0c;城市交通领域涌现了大量新技术。有时候我们不仅仅需要独立应用这些新技术来实现交通的变革&#xff0c;更需要将它们巧妙地结合连接起来&#xff0c;以获取更高效更安全的交通环境。本文将探讨V2X技术与智能传感器的结合&#xff0c;如何在城市…

uni-app打包证书android

Android平台打包发布apk应用&#xff0c;需要使用数字证书&#xff08;.keystore文件&#xff09;进行签名&#xff0c;用于表明开发者身份。 Android证书的生成是自助和免费的&#xff0c;不需要审批或付费。 可以使用JRE环境中的keytool命令生成。 以下是windows平台生成证…

1升级powershell后才能安装WSL2--最后安装linux--Ubuntu 22.04.3 LTS

视频 https://www.bilibili.com/video/BV1uH4y1W7UX特殊开启–Hyper-V虚拟机 把一下代码保存到【a.bat】的执行文件中&#xff0c;进行Hyper-V虚拟机的安装开启【Windows 批处理文件 (.bat)】 pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mu…

elasticsearch的数据搜索

DSL查询文档 elasticsearch的查询依然是基于JSON风格的DSL来实现的。 Elasticsearch提供了基于JSON的DSL(Domain Specific Language)来定义查询。常见的查询类型包括: 查询所有:查询出所有数据,一般测试用。例如:match_all 全文检索(full text)查询:利用分词器对用户…

鸿蒙Harmony应用开发—ArkTS(@Styles装饰器:定义组件重用样式)

如果每个组件的样式都需要单独设置&#xff0c;在开发过程中会出现大量代码在进行重复样式设置&#xff0c;虽然可以复制粘贴&#xff0c;但为了代码简洁性和后续方便维护&#xff0c;我们推出了可以提炼公共样式进行复用的装饰器Styles。 Styles装饰器可以将多条样式设置提炼…

学点儿Java_Day9_String、包装类

1 String 详解“”和equals的区别 Testpublic void test1() {//"abc"双引号括起来的字符串&#xff1a;字符串常量&#xff0c;它也是一个对象// 1.8之后常量池放到堆&#xff0c;在常量池里面找有没有这个"abc"对象&#xff0c;// 如果常量池里面没有这…

是德科技keysight N1912A双通道功率计

181/2461/8938产品概述&#xff1a; Keysight(原Agilent) N1912A P系列双通道功率计可提供峰值、峰均比、平均功率、上升时间、下降时间、最大功率值、最小功率值以及宽带信号的统计数据。 Keysight(原Agilent) N1912A P系列双通道功率计, 可提供峰值、峰均比、平均功率、上升…

nodejs各版本下载

https://registry.npmmirror.com/binary.html 然后进入nodejs各个版本&#xff0c;然后按需选择

JAVA 栈和队列总结

除了最底层下面三个是实现类&#xff0c;其他都是接口。 双端队列&#xff08;队头队尾都可以插入和删除元素&#xff09;的方法&#xff1a; 普通队列方法&#xff1a; 常用的是add(),poll(), element() 我们用Deque(双端队列)实现栈 Deque当栈用的时候的方法。 deque.push…

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序?

百度小程序入口在哪里找到怎么打开百度词令关键词口令直达小程序&#xff1f; 一、百度搜索找到百度词令小程序 打开手机百度搜索「词令」即可找到百度词令关键词口令直达小程序&#xff1b; 二、百度小程序中心找到百度小程序 2.1、打开手机百度&#xff0c;点击底部我的&a…

解决用POI库生成的word文件中的表格在python-docx无法解析的问题

问题背景 用apache-poi生成word文件中表格&#xff0c;在使用python-docx库解析时报错&#xff1a; 问题分析 1. word文档本质上是一个rar压缩包&#xff0c;用winrar解析后如下&#xff1a; 2. 查看document.xml&#xff0c;可以看到table元素下面是没有<w:tblGrid>这…