隨著程式設計語言的演化,我們可以看到一個非常明顯的趨勢:讓電腦去理解程式員,而不是程式員去理解電腦。從C#3.0中Lambda運算式可以明顯看出這一點來。
現在看個例子:
//使用C# 2.0 中的匿名方法尋找“內部包含Lambda子串的所有字串”:
list.FindAll(
delegate(string s) ...{
return s.Indexof(“Lambda”) > =0; }
);
//使用C# 3.0 中的Lambda運算式尋找“內部包含Lambda子串的所有字串”:
list.FindAll(s=>s.Indexof(“Lambda”) >= 0);
我們看到在Lambda運算式中用到了一個新的符號"=>"類似於數學上的"推匯出",我們在這裡簡單地稱它為"推出"。上面的意思就是由s推出s裡麵包含字串"Lambda"的字串。至於s的類型則由編譯器推導得出。這種表現形式比較符合人的思維模式。我們在數學上經常會用到由什麼推出什麼,聽起來很自然。Lambda運算式不是微軟首創,這個是學術界研究的成果,但是微軟卻把它第一個引入到了程式設計語言中。
下面看一下Lambda的格式:
/**//*(參數列表)=>運算式或者語句塊
可以有多個參數,一個參數,或者無參數。參數類型可以隱式或者顯式。*/
//例如:
(x, y) => x * y //多參數,隱式類型=> 運算式
x => x * 10 //單參數, 隱式類型=>運算式
x => ...{ return x * 10; } //單參數,隱式類型=>語句塊
(int x) => x * 10 // 單參數,顯式類型=>運算式
(int x) => ...{ return x * 10; } // 單參數,顯式類型=>語句塊
() => Console.WriteLine() //無參數
我們可以看出Lambda運算式非常的靈活。參數類型都可以省略,有編譯器去推導。而Lambda運算式的實質是什麼呢?用ILDasm開啟一個程式集看一下知道,其實還是匿名方法。只不過這些工作由編譯器替你做了。
下面用幾個例子說明一下編譯器做的工作:
//就拿list.FindAll( s=>s.Indexof(“abc”) > 0 );這句來說,看看編譯器在背後產生了哪些東西
delegate bool MyDelegate1(string s);
MyDelegate md1=new MyDelegate(XXXXX); //XXXXX為下面方法的名字
list.FindAll(md1);
public static bool XXXXX (string s) //XXXXX是方法的名字
...{
return s=>s.Indexof(“abc”) > 0;
}
/**//*這種寫法是不是很熟悉,沒錯這就是在C#1.0中的寫法,別管是C#2.0中的匿名方法還是
C#3.0中的Lambda運算式都會被編譯器轉化成這種形式*/
我們再來看一下Lambda的簡單舉例:
delegate int Delegate1(int a,int b);
delegate double Delegate2(double a,double b);
delegate string Delegate3(string s1,string s2(;
public class LambdaExpression
...{
public static void DoSomething(Delegate1 d1)...{....}
}
//我們就可以用下面的方法調用DoSomething
LambdaExpression.DoSomething((a,b)=>a+b); //這裡a,b和‘+’都可以換成別的變數名稱或者其他動作符
/**//*現在我們可以推斷出a,b的類型都為int,因為DoSomething的參數為Delegate1,而Delegate1的要求方
法的參數為int,所以很自然的推匯出a,b為int類型*/
//如果我們這樣寫DoSomething方法
public static void DoSomething(Delegate3 d3)...{....}
//然後這樣調用
LambdaExpression.DoSomething((s1,s2)=>s1+s2);
//很明顯s1,和s2將被推匯出為string類型
//至於編譯器在背後做了那些更細緻的工作,我們上面已經說過了,這裡不再細說
Lambda運算式L可以被轉換為委託類型D,需要滿足以下條件:
• L和D擁有相同的參數個數。
• L的參數類型要與D的參數類型相同。注意隱式類型要參與類型辨析。
• D的傳回型別與L相同,無論L是運算式,還是語句塊。
只要滿足了上述條件,在可以使用委託表達的地方就可以使用Lambda運算式
我們看到其實Lambda運算式只是對匿名方法的換一種形式表達,但是帶來的意義卻不只是這些,隨著越來越多的使用Lambda運算式你就會越來越覺得原來的那種匿名方法寫法很笨,你就會不願意再去使用那種方法。就好像當人們習慣了物件導向語言給我們帶來的編程方便時,而沒有人在想去用C語言寫出物件導向的程式一樣。