匿名方法 VS Lambda表示式
一、匿名方法:
引入背景:
C#引入匿名方法是為了簡化代理函式(delegate method)定義。
關於anonymous method的語法參考官網。
留心容易被忽略的地方:
1. 匿名方法不能訪問外部方法的ref和out引數。
Why?!
不安全
2. 匿名方法內的區域性變數不可以與外部方法的區域性變數重名,否則編譯會報重定義錯誤。
Why? !
C#的作用域最小單元是方法作用域,所以方法內的所有變數是不能重名的。雖然匿名方法也是一種“方法”,但是他被定義在方法內,所以應該也遵循最小作用域的原則。
像for,do-While等語句也遵循這個原則。匿名方法內的區域性變數可以與外部類的成員變數同名(作用域不同啊,當然可以了^_^)。
3. 匿名方法可以訪問外部方法定義的區域性變數,也可以訪問外部類成員方法和成員變數(即使是訪問許可權是Private的成員)。
這會使得所引用的外部變數或者外部類的成員變數生命週期變長。
3-1: 匿名方法引用外部方法區域性變數:
class MyAnonymous
{
public Func<int> ReturnFun()
{
int result = -1;
return delegate
{
return result;
};
}
static void Main(string[] args)
{
MyAnonymous a = new MyAnonymous();
Func<int> f = a.ReturnFun();
Console.WriteLine(f());
}
}
結果輸出:-1
按理說方法ReturnFun執行完後,其內部的區域性變數result的生命週期就完了,但是由於匿名方法類引用了該區域性變數,所以區域性變數result的生命週期並沒有結束,而是被延長了直到指向其所在的匿名方法的delegate生命週期結束。
3-2:匿名方法引用外部類成員:
類似3-1。
總體說如果匿名方法引用了外部變數(外部方法的區域性變數或者外部類成員)就好比增量一個訪問外部變數的方式(通過匿名方法)。
二、Lambda表示式
引入背景:
更方便的書寫匿名錶達式,他的引入就是為了簡化匿名方法的書寫。所以在使用到匿名方法的地方,以及對匿名方法的規則同樣適用於Lambda表示式。
但是!!!!官網上說兩者還是有點區別的:“有一種情況下,匿名方法提供了 Lambda 表示式中所沒有的功能。您可使用匿名方法來忽略引數列表。這意味著匿名方法可轉換為具有各種簽名的委託。這對於 Lambda 表示式來說是不可能的”。簡單的來講就是匿名方法可以省略形參,而Lambda表示式不可以省略。
舉例說明:
Func<int, int> func = delegate(int p)
{
return 1990;
};
這個表示式可以省略形參簡寫為:
Func<int, int> func = delegate //注意這個地方省略的形參。
{
return 1990;
};
而對於Lambda表示式來說不能省略形參,必須顯示的指明形參:
Func<int, int> func = i => 1990;
不能簡寫成:
Func<int, int> func = () => 1990;