最近實習早出晚歸很累,一直沒有更新!額,基礎還是要鞏固的!
匿名函數
在學習委託時,有個概念叫做匿名函數:即不需要在外部定義方法,直接在初始化委託時申明方法。先來看一個例子。
class Program { static void Main(string[] args) { //ad指向匿名函數 //delegate(參數列表){方法體} AnonyDelegate ad = delegate(string str) { Console.WriteLine(str); }; //調用委託 ad("Hello World"); Console.ReadKey(); } //申明委託 public delegate void AnonyDelegate(string s); }
其實在調用時,匿名函數的參數的清單類型必須對應定義委託的參數清單類型,每次都需要自己去手動寫。那麼,能不能有一種方法能讓編譯器自動推斷委託的參數清單類型呢?此時,Lambda 運算式就可以協助我們處理這個問題了。
使用Lambda運算式:
static void Main(string[] args) { //能夠根據委託推斷出參數的清單類型,比匿名函數更簡單 AnonyDelegate ad = (str) =>{ Console.WriteLine(str); }; //調用委託 ad("Hello World"); Console.ReadKey(); } //申明委託 public delegate void AnonyDelegate(string s);
Lambda運算式
對於Lambda運算式的一些介紹,msdn也講得挺清晰的。
"Lambda運算式"是一個匿名函數,它可以包含運算式和語句,並且可用於建立委託或運算式樹狀架構類型。
所有 Lambda 運算式都使用 Lambda 運算子 =>,該運算子讀為"goes to"。 該 Lambda 運算子的左邊是輸入參數(如果有),右邊包含運算式或語句塊。 Lambda 運算式 x => x * x 讀作"x goes to x times x"。這句話可以簡單的總結為Lambda 運算式的文法結構:
(輸入參數)=> 運算式
注意點:
(1)當Lambda 只有一個輸入參數時,可以省略括弧,但其他情況是必須要加的。
//當只有一個輸入參數時,可以省略括弧 AnonyDelegate ad = str =>{ Console.WriteLine(str); };
(2)當只有一個空的括弧時,表示沒有參數。
AnonyDelegate2 ad2 = () => { Console.WriteLine("Hello World"); }; //申明委託 public delegate void AnonyDelegate2();
(3)當lambda運算式中的匿名函數的方法體如果只有一句話,並且是傳回值,那麼可以省略{}以及return,就把=>後的運算式做為傳回值
//申明委託 public delegate bool AnonyDelegate3(string str); AnonyDelegate3 ad3 = (str) => str == "Hello World"; Console.WriteLine(ad3("Hello World"));
Lambda運算式使用情境
這一塊內容相對比較重要,Lambda運算式現在應用很廣,例如查詢運算式,所以需要掌握這個基礎知識。
Lambda 在基於方法的 LINQ 查詢中用作標準查詢運算子方法(如 Where等)的參數。
使用基於方法的文法在 Enumerable 類中調用 Where 方法時(像在 LINQ to Objects),參數是委託類型 System.Func<T, TResult>。 使用 Lambda 運算式建立委託很方便。 例如,當您在 System.Linq.Queryable 類中調用相同的方法時,則參數類型是 System.Linq.Expressions.Expression<Func>,其中 Func 是包含至多十六個輸入參數的任何 Func 委託。 同樣,Lambda 運算式只是一種用於構造運算式樹狀架構的非常簡練的方式。
使用Lambda運算式如何篩選數組中大於0的數呢?其實非常簡單!
int[] values = { -8, 2, 13, -5, 9 }; IEnumerable<int> result = values.Where(s => s > 0); foreach (var val in result) { Console.WriteLine(val); } Console.ReadKey();
那麼為什麼直接可以使用該方法呢?我們轉到where的方法定義,可以看到
public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate);
Tsource:source 中的元素的類型。這裡指int類型。
source:類型為System.Collections.Generic.IEnumerable<TSource>。要篩選的 IEnumerable<T>。這裡指values數組。
predicate:類型為System.Func<TSource, Boolean>。用於測試每個元素是否滿足條件的函數。這是指方法體的實現。
傳回值:一個 IEnumerable<T>,包含輸入序列中滿足條件的元素。這裡指返回IEnumerable<T>。
Func<TSource,bool> :實際上是泛型委派的 Func<T, TResult> 系列的其中之一。 Func<T, TResult> 委託使用型別參數定義輸入參數的數目和類型,以及委託的傳回型別。這是指int為輸入參數,bool是傳回型別。
同理其他的方法原理差不多。輕描淡寫,下階段再寫深入些的!
作者: ForEvErNoME
出處: http://www.cnblogs.com/ForEvErNoME/
歡迎轉載或分享,但請務必聲明文章出處。如果文章對您有協助,希望你能 推薦 或 關注