Lambda 表達式是一種可用于創建委托或表達式目錄樹類型的匿名函數。通過使用 lambda 表達式,可以寫入可作為參數傳遞或作為函數調用值返回的本地函數。以上是msdn官網對Lambda 表達式的描述。實質上Lambda 表達式可以說是從匿名方法推演而來,微軟程序員為了提高我們廣大程序員的生產效率推出了Lambda 表達式,它的出現無疑是極具影響力的。
Lambda 表達式使用Lambda 運算符=>,我們一般讀作“goes to”,當然這并不是說它跟C#中的goto有相同的含義,只是都有“轉到”的意思罷了。Lambda 表達式的書寫規則如下:
參數列表=>表達式
現在就讓我來講解下從匿名方法到Lambda 表達式的推演過程。以上篇博文的例子為例,
//假設需要從list集合中獲取大于3的所有元素以新集合返回List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6 };var newlist = list.FindAll(delegate(int i) { return i > 3; });這是用匿名方法實現的寫法。微軟程序員覺得這樣子不夠簡單,為了簡便寫法,便有了如下的推斷過程。
首先既然你總是要傳入一個匿名方法,總是會有delegate這個關鍵字,于是可以考慮將delegate去掉。去掉了delegate,那么書寫就不規范了,于是就引入了=>運算符用來連接參數列表與表達式,這樣上式便變成:
var newlist = list.FindAll((int i) => { return i > 3; });其次,int這個類型是可以推斷出來的,當用鼠標指到"FindAll"的時候就可以看到:
,
這便讓我們知道這里delegate后續的入參是int型(本例是int型,因為上面的集合是int型,實際上什么類型是看你自己需求的),于是再指定類型為int顯得有點多余,因此可以寫成這樣:
var newlist = list.FindAll((i) => { return i > 3; });而此時參數只有一個,因此括號也可以去掉:
var newlist = list.FindAll(i => { return i > 3; });然后,FindAll()需要傳入一個PRedicate<T>泛型委托,可以按F12看出該委托返回值類型為bool,同樣我們傳入的匿名方法必須與它具有相同的簽名,所以也要返回bool值。因為總是知道要返回什么類型的值,所以可以考慮去掉return關鍵字,而方法體里只有一句表達式,所以可以考慮去掉大括號,同時也將表達式后面多余的分號去掉,到了這個時候原本的方法體已變成i>3這么個表達式,其等價于一個bool值,可以類比if(i>3)來理解,多個return關鍵字不過是為了返回值以符合方法定義的規范。于是原來的式子又演變成了:
var newlist = list.FindAll(i => i > 3 );
這就是Lambda 表達式。
看了上面的例子或許有人會有這樣的疑惑,=>右邊就只能寫一句表達式,那么如果我要執行很復雜的邏輯怎么辦?事實上,可以這樣寫:
List<int> newlist = list.FindAll( (int i) =>//小括號和int可以同時省略,也可以只省略int,不能只省略小括號留int { //這里可以寫復雜的邏輯,下面只是示例,當然可以直接return i>3;效果和上面的一樣 Console.WriteLine("原集合有如下數字:{0}", i); bool b = i > 3; return b; });之前的例子是因為=>左邊的參數只有一個才可以省略小括號,實際上,當參數不止一個的時候,則不能省略小括號,例如:(i,j)=>表達式或語句塊
如果沒有參數,可以這樣寫:()=>表達式或語句塊
從匿名方法到Lambda 表達式可以說一個優化演變的過程,Lambda 表達式是一個委托類型,它和匿名方法一樣可以傳遞為委托參數。
新聞熱點
疑難解答