Csharp学习Linq

这篇具有很好参考价值的文章主要介绍了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差不多的样子.
Csharp学习Linq

再去看一下它的movenext函数.

Csharp学习Linq

这个就是一个yield return反汇编出来的状态机的代码。文章来源地址https://www.toymoban.com/news/detail-841437.html

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
 }

到了这里,关于Csharp学习Linq的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 计算机视觉(三)未有深度学习之前

    把图像划分成若干互不相交的区域。 经典的数字图像分割算法一般是基于灰度值的两个基本特征之一:不连续性和相似性。 基于阈值:基于图像灰度特征计算一个或多个灰度阈值。将灰度值与阈值比较,最后将比较结果分到合适的类别中。 大津法 基于边缘:边界线上连续的

    2024年02月15日
    浏览(39)
  • 如何在任何STM32上面安装micro_ros(貌似这个文章里面已经没有什么可以继续阻挡我的了,我有gitee和docker,虽然docker其实用不着)

    JMP推荐跳转到此篇文章==STM32CubeMX+micro_ros_stm32cubemx_utils库-CSDN博客 就我知道的:micro-ros只能在特定的昂贵的开发板上面运行,但是偶然发现了这个文章,似乎提供了一个全新的方式来在ros2和单片机之间通讯,如果能够这样肯定也能够提高效率,但即使不行,使用串口库也应该

    2024年02月22日
    浏览(30)
  • Docker学习之前需要了解的几个概念

    1.1. 命名空间(Namespaces) 命名空间是Linux内核提供的资源隔离机制,它通过创建多个独立的 全局视图 ,使得在不同命名空间中的进程可以拥有各自独立且互不干扰的系统资源。每个命名空间提供了一种逻辑上的隔离效果,让进程看到的是一个受限或定制化的环境,而非整个

    2024年01月23日
    浏览(49)
  • PMP如何备考?学习方式这里有

    预习阶段: 强烈建议跟着习课视频学习(自己看书真的很难看懂),初步了解PMBOK,有个大致印象; 精讲阶段: 这个时候就需要静下心来深入了解各个知识模块,不仅是看PMBOK,还要尽量去理解晦涩难懂的知识,细化到每一个大的知识点,打好知识的基础,后面你会发现PM

    2024年02月11日
    浏览(24)
  • 继续学习Easyx

    画圆角矩形函数: roundrect ,前四个参数是和矩形一样的,表示先画一个矩形,然后就是要画它的圆角了,要怎么画它的圆角?这里使用四个一样的椭圆来将它的四个角画出来,而在这个里面的椭圆不再需要四个参数也就是两个点了,这里每个椭圆的一个点已经确定,我们只

    2023年04月21日
    浏览(16)
  • Pytorch--模型微调finetune--迁移学习 (待继续学习)

    https://www.bilibili.com/video/BV1Z84y1T7Zh/?spm_id_from=333.788vd_source=3fd64243313f29b58861eb492f248b34 torchvision 微调 timm 微调 半精度训练 大模型无法避免过拟合,

    2024年02月11日
    浏览(33)
  • Session详解,学习Session,这篇文章就够了(包含底层分析和使用)

            说明:下面介绍session,我们使用到了游览器抓包,http的知识,如果不了解,请先简单了解下。http介绍,http请求,http响应。因为cookie和session是一对”好兄弟“,我们介绍session也要使用到cookie,如果不清楚cookie,请查看cookie详解。废话不多说,直接开始吧。     

    2024年02月03日
    浏览(25)
  • 机器学习之前向传播(Forward Propagation)和反向传播(Back propagation)

    前向传播(Forward Propagation)和反向传播(Back propagation)是深度学习中神经网络训练的两个关键步骤。 前向传播(Forward Propagation) : 定义 :前向传播是指从神经网络的输入层到输出层的过程,通过输入数据和当前的模型参数,计算网络的输出。 步骤 :在前向传播中,数据

    2024年02月10日
    浏览(40)
  • 学习网络安全有哪些误区?学习之前要做哪些准备?如何系统的学习黑客技术/网络安全?

    如果你想学习网络安全,首先你必须了解什么是网络安全!什么是黑客! 1.无论网络、Web、移动、桌面、云等哪个领域,都有攻与防两面性,例如 Web 安全技术,既有 Web 渗透 2.也有 Web 防御技术(WAF)。作为一个合格的网络安全工程师,应该做到攻守兼备,毕竟知己知彼,才

    2024年02月05日
    浏览(55)
  • 〖程序员的自我修养 - 认知剖析篇②〗- 学习编程之前你需要知道这些

    人之所以会觉得迷茫,本质上是欠缺对自己的一个控制力、识别庞杂信息、去伪存真的独立思考与认知能力。 说明:该文属于 程序员的自我修养 专栏, 购买任意白宝书体系化专栏可加入 易编程社区, 早鸟价订阅模式除外 。 福利:加入社区的小伙伴们,除了可以获取博主

    2024年02月12日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包