本章節給大家帶來的是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是不一樣的!
