大家在開發中會經常看到也會經常使用lambda表達式。
園子裡也有很多詳解lambda表達式的文章,多是從橫向來講述。
但lambda表達式到底如何變成現在這個樣子,表達式的形式到底代表什麼含義,這些可能就不太明白了。
本文將從來源開始,縱向剖析,一直演化出我們常用的lambda表達式。
引子
為方便說明,先舉個例子,列出Lambda表達式的一個典型形式:
x=>x+1
大家可以看到,Lambda表達式的語法由三部分組成,分別為:
1. Lambda運算符 => 讀作goes to;
2. 左邊參數部分 x ;
3. 右邊的Lambda主體
可以看出,其實所謂的Lambda表達式(lambda expression)就是一個匿名函數,或者說是匿名函數的簡單形式。而匿名函數的作用就是分配給委托類型的。
假設我們聲明一個委托:
delegate int Mydel(int x);
lambada 表達式(匿名函數)用來填充委托變量:
Mydel del= x=>x+1;
我們就從這個例子說開去。
演化過程
剛剛說過,lambda表達式就是匿名方法的簡寫形式,說到lambda表達式就要說到匿名方法,而匿名方法就是初始化委托時內聯聲明的方法。
因此我們先從委托說起,一直推導出 lambda表達式Mydel del=x=>x+1; 的形式。
和類相似,委托是用戶自定義的引用類型。
類表示的是數據和方法的集合,而委托則持有一個或多個方法,以及一系列預定義操作。
可以將委托類比為類,創建和使用的過程如下:
1.聲明類型
2.聲明類型的變量
3.填充變量
4.使用變量
對應著四步的完整例子:
delegate int Mydel(int x);
Mydel del;
del=new Mydel(xxx方法); //也可以直接用簡化寫法 del=xxx方法;
del(2);
以上第三步中初始化委托使用 xxx方法 。
如果方法專門用來初始化委托,只會被使用一次,這種情況下,除了創建委托的語法需要,沒有必要創建獨立的具名方法,這樣就引出了匿名方法。
匿名方法是在初始化委托時內聯聲明的方法,非匿名方法的例子如下:
public static int Add1(int x)
{
return x+1 ;
}
delegate int MyDel(int x);
調用:
MyDel del=Add1;
del(2);
改造成用匿名方法的完整例子:
delegte int MyDel(int x);
調用:
MyDel del=delegate(int x) { return x+1;}
del(2);
從例子中提取出匿名方法的語法:
delegate(Parameters) { ImplementationCode }
幾個注意點:
1. 返回值:不顯示聲明返回值,與委托相同
2. 參數
以下情況可以使用圓括號為空或省略圓括號來簡化參數列表。
a. 不包括任何out 參數 b. 不使用任何參數
滿足上面兩個條件即可省略參數列表,例子:
delegate int SomeDel(int x);
SomeDel sDel = delegate { return 1; };
3.params 參數
如果委托聲明的參數列表包含了 params 參數(可變數目參數),匿名方法的參數列表將忽略params關鍵字
delegate void SomeDel(int x, params int[] y);
SomeDel sDel = delegate(int x, int[] y) { … }
匿名方法准備好了,我們稍加變化,就可以得出Lambda表達式
以 MyDel del=delegate(int x) { return x+1;} 為例。
轉換步驟:
1.刪除delegate關鍵字,在參數列表和匿名方法主體之間放 =>
MyDel del = (int x) => {return x+1; } ;
可以進一步簡化
2. 去掉參數類型
MyDel del2 = (x) => {return x+1; } ;
說明:
編譯器可以從委托聲明中知道委托參數的類型,因此可以省略類型。
帶有類型的參數列表稱為顯式類型。
省略類型的參數列表稱為隱式類型。
3.去掉參數刮號
MyDel del3 = x => {return x+1; } ;
說明:
如果只有一個隱式類型參數,可以省略刮號。
4.去掉主體的大刮號及return
MyDel del4 = x=> x+1;
說明:
Lambda表達式允許表達式的主體是語句塊或表達式。
如果語句塊包含一個返回語句,可以將語句塊替換成return 後面的表達式。
這樣就得到我們文章開頭的形式。
總結
C#2.0引入了匿名方法,C#3.0引入了lambda表達式,可以看到,lambda表達式簡化了匿名函數的使用,讓代碼更加簡潔。
理解了這篇文章,相信大家對lambda表達式就會有一個整體的把握,再學具體用法時思路會很清晰。
祝學習進步~