1. 程式人生 > >匿名方法 VS Lambda表示式

匿名方法 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;