本章节给大家带来的是Lambda 和 Linq 的关系
Lambda : 是实例化委托的一个参数,也就是一个方法
Linq:是基于委托(lambda)的封装,代码重用,逻辑解耦,是一个帮助类库,linq是用泛型,委托,lamda实现的,总的来说:把对数据操作的通用部分完成,把可变的交给委托,使用者只关心可变部分。
一、Lambda
文章的开始已经说明Lambda是实例化委托的一个参数,也就是一个方法。那么我们通过代码来体现一下:
{ //.NetFramework 1.0-1.1的时候这样应用 NoReturnNoPara method = new NoReturnNoPara(DoNothing); method.Invoke(); //.NetFramwork2.0 匿名方法出现,delegate关键字,可以访问局部变量 int i = 0; NoReturnWithPara method1 = new NoReturnWithPara(delegate (int id, int age) { Console.WriteLine(i); Console.WriteLine($"{id} 今年{age}岁了!"); }); method1.Invoke(1, 30); //.NetFramwork3.0 把delegate关键字去掉,然后增加了一个箭头goes to //lambda表达式:参数列表=>方法体 NoReturnWithPara method2 = new NoReturnWithPara((int id, int age) => { Console.WriteLine(i); Console.WriteLine($"{id} 今年{age}岁了!"); }); method2.Invoke(1, 30); NoReturnWithPara method3 = new NoReturnWithPara((id, age) => { //省略参数类型,但是编译器可以根据委托推断出类型,是语法糖 Console.WriteLine(i); Console.WriteLine($"{id} 今年{age}岁了!"); }); method3.Invoke(1, 30); //如果方法体只有一行,可以去掉大括号和分号 NoReturnWithPara method4 = new NoReturnWithPara((id, age) => Console.WriteLine($"{id} 今年{age}岁了!")); method4.Invoke(1, 30); //如果方法体只有一行,可以去掉大括号和分号,还可以去掉new NoReturnWithPara,这个也是编译器语法糖 NoReturnWithPara method5 = (id, age) => Console.WriteLine($"{id} 今年{age}岁了!"); method4.Invoke(1, 30); //下面带有返回值的 Func<int> func0 = () => { return DateTime.Now.Month; };//有一个返回值 Func<int> func1 = () => DateTime.Now.Month; //如果方法体只有一行,去掉大括号分号和return }
使用反编译工具看会产生一个私有sealed类,然后会看到lambda表达式都会生成一个方法名字,然后都会在包括在Sealed类里面
二、Linq
很多人会把Linq和lambda混淆,面试的时候问lambda是什么,很多同学反问不就是Linq吗?
文章开头也讲述了Linq是基于委托(lambda)的封装,代码重用,逻辑解耦,是一个帮助类库,linq是用泛型,委托,lamda实现的,总的来说:把对数据操作的通用部分完成,把可变的交给委托,使用者只关心可变部分。接下来举个例子让大家可以更好的认识Linq和使用Linq
首先初始化一些基础数据:
private List<Student> GetStudentList() { #region 初始化数据 List<Student> studentList = new List<Student>() { new Student() { Id=1, Name="赵亮", ClassId=2, Age=35 }, new Student() { Id=1, Name="再努力一点", ClassId=2, Age=23 }, new Student() { Id=1, Name="王炸", ClassId=2, Age=27 }, new Student() { Id=1, Name="疯子科学家", ClassId=2, Age=26 }, new Student() { Id=1, Name="灭", ClassId=2, Age=25 }, new Student() { Id=1, Name="黑骑士", ClassId=2, Age=24 }, new Student() { Id=1, Name="故乡的风", ClassId=2, Age=21 }, new Student() { Id=1, Name="晴天", ClassId=2, Age=22 }, new Student() { Id=1, Name="旭光", ClassId=2, Age=34 }, new Student() { Id=1, Name="oldkwok", ClassId=2, Age=30 }, new Student() { Id=1, Name="乐儿", ClassId=2, Age=30 }, new Student() { Id=1, Name="暴风轻语", ClassId=2, Age=30 }, new Student() { Id=1, Name="一个人的孤单", ClassId=2, Age=28 }, new Student() { Id=1, Name="小张", ClassId=2, Age=30 }, new Student() { Id=3, Name="阿亮", ClassId=3, Age=30 }, new Student() { Id=4, Name="37度", ClassId=4, Age=30 } , new Student() { Id=4, Name="关耳", ClassId=4, Age=30 } , new Student() { Id=4, Name="耳机侠", ClassId=4, Age=30 }, new Student() { Id=4, Name="Wheat", ClassId=4, Age=30 }, new Student() { Id=4, Name="Heaven", ClassId=4, Age=22 }, new Student() { Id=4, Name="等待你的微笑", ClassId=4, Age=23 }, new Student() { Id=4, Name="畅", ClassId=4, Age=25 }, new Student() { Id=4, Name="混无痕", ClassId=4, Age=26 }, new Student() { Id=4, Name="37度", ClassId=4, Age=28 }, new Student() { Id=4, Name="新的世界", ClassId=4, Age=30 }, new Student() { Id=4, Name="Rui", ClassId=4, Age=30 }, new Student() { Id=4, Name="帆", ClassId=4, Age=30 }, new Student() { Id=4, Name="肩膀", ClassId=4, Age=30 }, new Student() { Id=4, Name="孤独的根号三", ClassId=4, Age=30 } }; #endregion return studentList; }
只要实现了IEnumerable这个接口,都是可以使用 where,Count等方法,只要底层是实现IEnumerable的,都是linq to object
linq To object 是.netFramwork3.0的一个非常重大的改变
下面展示一下linq to object 的几种使用方式
#region linq to object Show { Console.WriteLine("********************"); var list = from s in studentList where s.Age < 30 select s; foreach (var item in list) { Console.WriteLine("Name={0} Age={1}", item.Name, item.Age); } } { Console.WriteLine("********************"); var list = studentList.Where<Student>(s => s.Age < 30) .Select(s => 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)//排序 .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}"); } } List<Class> classList = new List<Class>() { new Class() { Id=1, ClassName="初级班" }, new Class() { Id=2, ClassName="高级班" }, new Class() { Id=3, ClassName="微信小程序" }, }; { var list = from s in studentList join c in classList on s.ClassId equals c.Id 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
linq to sql 运用的是表达式目录树,这个底层是实现的IQueryable,概念和linq to object是不一样的!