進入正題之前, 請容我扯一段往事. 話說我們大學的時候, 系上有一位姓包的老教授, 人稱老包. 他是一個鐵面無私的老師, 三次點名不到必當, 所以很容易和開封府的包大人聯想在一起.
老包教的科目裡面有一科電力機械, 這本沉悶的教科書裡面用到一大堆的 γ 和 λ 符號; 所以老師言必稱 γ 和 λ . 敝人修完這堂課, 最後唯一記得的也就是 "柑仔" (γ)那麼大 (λ)了. 後者即是今天的主角 – 那麼大.
由於現在的程式愈來愈複雜, 所以多餘的東西漸漸被捨棄不用. 在這種考量之下, 匿名函式 (Anonymous Fuction) 應運而生, 而 Lambda 運算式正是匿名函式的其中一種, 另外一種是匿名方法 (Anonymous Method). 匿名方法可以省略參數 (清單), 但是 Lambda 不能.
先來看看 Lambda 運算子. Lambda 運算子具有將左邊參數指派給右式的功能, 比方說:
1. Expression Lambda (運算式 λ):
(input parameters) => expression
delegate int del(int i);
static void Main(string[] args) {
del MySquare = x => x * x;
int j = mySquare(5); //j = 25
}
所以我們就不需要中規中矩地寫一個乘方的函數, 而是草草帶過, 有正確答案就好.
或曰, 為什麼不用 macro 來代替呢? 其實 Lambda 的功力並非只有這樣.
2. Statement Lambda (陳述式 λ)
(input parameters) => {statement;}
delegate void ShowHelloWorld(string s);
…
ShowHelloWorld myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; // 一行文函式
myDel("Hello");
結果當然是輸出 Hello World.
大家可以看得出來, 使用 Lambda 很像是寫 script, 只要意思不會搞錯, 字串或是數值都用一樣的寫法. 只要把握基本的原則, Lambda 就可以快速地為大家服務.
以下是 Lambda 的一般規則:
1. Lambda 必須包含與委派型別相同數目的參數。
2. Lambda 中的每個輸入參數都必須能夠隱含轉換為其對應的委派參數。
3. Lambda 的傳回值 (如果存在) 必須能夠隱含轉換為委派的傳回型別。
特別值得一提的是傳回值, 它使用 delegate 後面委派的型別, 如第一例中的 int, 和第二例中的 void.
Lambda 運算可以出現在 Visual Basic 或 C# (3.0) 之中. 上面舉的例子都是 C#, 此時會使用到 Lambda 運算子 =>.
歷代 C# 使用委派的歷史可以看這個例子, C# 2.0 開始用匿名方法, 直到 C# 3.0 之後才使用 Lambda.
class Test
{
delegate void TestDelegate(string s);
static void M(string s)
{
Console.WriteLine(s);
}
static void Main(string[] args)
{
// Original delegate syntax required
// initialization with a named method.
TestDelegate testDelA = new TestDelegate(M);
// C# 2.0: A delegate can be initialized with
// inline code, called an "anonymous method." This
// method takes a string as an input parameter.
TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };
// C# 3.0. A delegate can be initialized with
// a lambda expression. The lambda also takes a string
// as an input parameter (x). The type of x is inferred by the compiler.
TestDelegate testDelC = (x) => { Console.WriteLine(x); };
// Invoke the delegates.
testDelA("Hello. My name is M and I write lines.");
testDelB("That's nothing. I'm anonymous and ");
testDelC("I'm a famous author.");
// Keep console window open in debug mode.
Console.WriteLine("Press any key to exit.");
Console.ReadKey();
}
}
/* Output: Hello. My name is M and I write lines. That's nothing. I'm anonymous and I'm a famous author. Press any key to exit. */
不過 VB 裡面沒有特定的 Lambda 運算子, 只有 Lambda 運算式, 例如:
Dim doubleIt As Func(Of Integer, Integer) = _ Function(x As Integer) x * 2
詳請可以看這一篇: Lambda 運算式