Lambda表達式與匿名方法的區別
那麼,為什麼Lambda表達式比匿名方法寫起來要短呢?這種像變戲法一樣的手法真的能用嗎?有沒有重要信息遺漏掉呢?為了回答這些問題,就讓我們把匿名方法和Lambda表達式比較一下,看看Lambda表達式究竟怎麼寫。
1using System;
2
3delegate int SampleDelegate(int x, int y);
4
5class Program
6{
7 private static void Calculate(int x, int y, SampleDelegate calculator)
8 {
9 Console.WriteLine(calculator(x, y));
10 }
11
12 static void Main(string[] args)
13 {
14 // 匿名方法
15 Calculate(1, 2,
16 delegate(int x, int y) { return x + y; }); // 輸出:3
17
18 // Lambda表達式
19 Calculate(1, 2, (x, y) => x + y); // 輸出:3
20 }
21}
22
List9 匿名方法與Lambda表達式的比較
這段代碼中,下述部分分別是匿名方法和Lambda表達式的寫法:
匿名方法
delegate(int x, int y) { return x + y; }
Lambda表達式
(x, y) => x + y
字面上比較一下就能發現以下不同:
* delegate關鍵字沒有了
* return關鍵字沒有了
* 指定參數的類型的int沒有了
* 中括號“{ }”沒有了
* 行尾的分號“;”沒有了
* 新出現了“=>”這兩個字符
下面,對這些區別,一個一個來解釋。
首先,Lambda表達式使用的“=>”,叫“=>運算符”,讀作“向~輸入”(日本讀法,跟國情有關)。在上例中,就讀作“向x、y輸入 x+y”(雖這樣說,但如果不習慣也不必勉強這樣讀,筆者也不愛這樣讀,忒費勁)。delegate關鍵字並不是去掉了,如果理解為被“=>”運算符替換了的話可能更容易理解。這就是區分“匿名方法”與“Lambda表達式”的關鍵字。僅這一點,就從delegate的8個字母減到=>兩個字母,少了6個字母呢!(這賬算的,也不知是真傻還是精明過頭了。對我們C#程序員來說,敲入delegate恐怕要比敲入=>快多了。鬼知道=、& gt;這兩個字符在哪個鍵上,每次都要低頭去找,還要按Shift,麻煩!)
其次,return這個關鍵字,因為Lambda表達式本身就是“表達式”,所有舊沒有必要再return了(如果是代碼段的話,就又需要return了,後面詳述)。例如:
int method() { return 1 + 2; }
這種情況下return還需要。但這種情況:
1 + 2
就不需要再return了。這裡去掉return,又減去6個字符。(大汗)
參數類型不需要指定了,有些人可能會擔心對於類型檢查是不是太草率了,有人可能會竊喜不用再費事去聲明類型了,切實這兩種人都錯了。List 9,Calculate方法的參數是SampleDelegate類型的,SampleDelegate代理的參數是2個int類型的,已經聲明過了。所以不用再一次聲明,x和y已經可以確定是int類型了。
這裡再補充一點,這些其實都不是Lambda表達式所特有的。匿名方法雖確實需要顯式的把參數類型寫上,返回值的類型卻采用了同樣方法來推斷。反過來說,如果不能夠進行這樣的推斷,那麼匿名方法和Lambda表達式都不能使用。類型不確定的場合下,是不能夠使用的。這一點要記住。
接下來是中括號{ }和行尾的分號;的省略,其理由其實和return的理由是一樣的,因為Lambda表達式本身就是表達式(相反,加上中括號{ }的就是“Lambda語句”,後文詳述)。
OK,講完收功。沒什麼神奇的,也不損失嚴密性,但其實現的代碼縮短能力卻是壓倒性的。
Lambda語句(日本人叫Statement型Lambda)
到目前為止見到的Lambda表達式,都是“表達式型的Lambda”。因為其都是按表達式的方法寫的而得名。
另外,還有一種內容按語句方式寫的“Lambda語句”。它不是簡單的表達式。如果要把較長代碼寫入Lambda的話還是Lambda語句好用。書寫方式也簡單,就是用中括號括起來就行了。
以下是一個例子:
using System;
class Program
{
static void Main(string[] args)
{
// Lambda語句
Action<string> method = (filename) =>
{
if (filename == null)
Console.WriteLine("Hello!");
else
System.IO.File.WriteAllText(filename, "Hello!");
};
method(null); // 輸出:Hello!
method("hello.txt"); // 生成hello.txt文件
}
}
Lambda語句有返回值得情況下就使用return。例如,下面的Lambda表達式換做Lambda語句的話:
表達式形式的Lambda
(n) => a == n;
語句形勢的Lambda
(n) => { return a == n; };
這個一看就明白了,文字上長了不少。但是,不能寫Lambda表達式,只能用Lambda語句的情況下,僅一個return的增加這樣的開銷還是能夠接受的。