|
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差不多的样子.
再去看一下它的movenext函数.
这个就是一个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
- }
复制代码 来源:https://www.cnblogs.com/wenlong-4613615/p/18073134
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?立即注册
x
|