Lambda的前世今生
Lambda的本質(zhì)是一個(gè)方法,多播委托中是不能把Lambda表達(dá)式-=祈匙,因?yàn)長(zhǎng)ambda表達(dá)式其實(shí)是一個(gè)方法忽刽,不同的lambda表達(dá)式就是不同的方法。
.Netframework1.0/1.1時(shí)代
NoReturnNoPara method = new NoReturnNoPara(DoNothing);
method .Invoke();
.NetFramework2.0時(shí)代夺欲,匿名方法增加了一個(gè)delegate關(guān)鍵字跪帝,可以訪(fǎng)問(wèn)到參數(shù)以外的局部變量
NoReturnWithPara method = new NoReturnWithPara(delegate (int id, string name)
{
Console.WriteLine($"{id} {name}...");
Console.WriteLine(i);
});
method.Invoke(123, "Test");
.NetFramework3.0時(shí)代,去掉delegate關(guān)鍵字些阅,添加一個(gè)=> "goes to"
NoReturnWithPara method = new NoReturnWithPara ((int id,string name)=>
{
Console.WriteLine($"{id} {name}...");
Console.WriteLine(i);
});
method.Invoke(123, "Test");
.NetFramework3.0 后期,去掉了匿名方法的參數(shù)類(lèi)型
NoReturnWithPara method = new NoReturnWithPara((id,name)=>
{
Console.WriteLine($"{id} {name}...");
Console.WriteLine(i);
});
method.Invoke(123, "Test");
** Linq使用**
相信在日常的開(kāi)發(fā)中伞剑,大家在對(duì)集合進(jìn)行處理事都使用過(guò)Linq,但不知道大家有沒(méi)有究其Linq的本質(zhì)呢?
下面我將使用代碼的方式將"List.Where()"進(jìn)行拆解開(kāi):
public static class MethodExtension
{
public static IEnumerable<T> CustomWhere<T>(this IEnumerable<T> resource, Func<T, bool> func) where T : class
{
List<T> list = new List<T>();
foreach (var item in resource)
{
if (func.Invoke(item))
{
list.Add(item);
}
}
return list;
}
}
public class App
{
public static void Main(string[] args)
{
//初始化集合
List<string> strList = new List<string>();
//定義函數(shù)體
Func<string,bool> func = (s=>{return s.Length > 10};);
//使用上述的擴(kuò)展方法
strList.CustomWhere(func);
//進(jìn)一步演化得到
strList.CustomWhere(s =>s.Lenght >10);
}
}
由上面的拆解發(fā)現(xiàn)市埋,其實(shí)Linq就是將我們可變的邏輯進(jìn)行封裝成委托來(lái)當(dāng)作參數(shù)進(jìn)行傳遞黎泣,而不變的邏輯封裝成方法體來(lái)接收可變的邏輯參數(shù),而這種思想也就是早期微軟特別推崇的“封裝思想”缤谎。
了解了“Linq”的基本原理后抒倚,那就在來(lái)看一下Linq中的其他封裝方法:
//Select--投影
var list = studentList.Where<Student>(s => s.Age < 30)
.Select(s => new
{
IdName = s.Id + s.Name,
ClassName = s.ClassId == 2 ? "2班" : "其他班"
});
foreach (var item in list)
{
Console.WriteLine("Name={0} Age={1}", item.ClassName, item.IdName);
}
//OrderBy,OrderByDescending坷澡,Skip托呕,Take
var list = studentList.Where<Student>(s => s.Age < 30)//條件過(guò)濾
.Select(s => new//投影
{
Id = s.Id,
ClassId = s.ClassId,
IdName = s.Id + s.Name,
ClassName = s.ClassId == 2 ? "2班" : "其他班"
})
.OrderBy(s => s.Id)//排序
.OrderByDescending(s => s.ClassId)//倒排
.Skip(2)//跳過(guò)幾條
.Take(3)//獲取幾條
;
foreach (var item in list)
{
Console.WriteLine($"Name={item.ClassName} Age={item.IdName}");
}
//GroupBy
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}");
}
//Join
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}");
}
//left Join
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 ? "無(wú)班級(jí)" : sc.ClassName//c變sc,為空則用
};
foreach (var item in list)
{
Console.WriteLine($"Name={item.Name},CalssName={item.CalssName}");
}