天天看點

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

較之前一個版本,對于C# 3.x和VB 9來說,LINQ是最具吸引力的。基本上很多的新的特性都是圍繞着LINQ的實作來設計的。借助Extension Method,我們可以為LINQ定義一系列的Operator。通過Lambda Expression我們可以為LINQ編寫更加簡潔的查詢。我們可以說這些新的特性成就了LINQ,也可以說這些新特性就是為了實作LINQ而産生,但是我們應該明白,對于這些新引入的特性,LINQ并非他們唯一的用武之地,在一般的程式設計中,我們也可以使用它們。

接下來,我将通過一個簡單的Demonstration,由淺入深地分析Lambda Expression,看看編譯器到底會編譯生成怎樣的額外的Code,他們的IL又是如何。

一、Named Delegate

在上面,我說了Lambda Expression本質上就是一個Delegate,我們先不直接來介紹Lambda Expression, 我們先來看看我們最為熟悉的Delegate的例子: 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

using System;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

using System.Collections.Generic;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

using System.Linq;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

using System.Text;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

namespace Artech.LambdaExpression

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

{

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

    class Program

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

    {

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

        static void Main()

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

        {

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            _namedMethodDelegate = new Function<int, bool>(SomeMethod);

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            Function<int, bool> function1 = _namedMethodDelegate;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            function1(20);     

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

        }

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

        private static Function<int, bool> _namedMethodDelegate;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

        private static bool SomeMethod(int args)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            return (args > 0);

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

    }

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

    delegate TResult Function<TArgs, TResult>(TArgs args);

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

}

上面的例子很簡單,先定一個Generic Delegate :Function。在Program Class中定義一個Static的Function字段_namedMethodDelegate和與之對應的Method:SomeMethod,判斷輸入的數字是否大于零。在Main中執行個體化_namedMethodDelegate,并調用它。

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

.method private hidebysig static void  Main() cil managed

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  .entrypoint

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  // Code size       34 (0x22)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  .maxstack  3

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function1)//Initialize function1

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0000:  nop

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0001:  ldnull

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0002:  ldftn      bool Artech.LambdaExpression.Program::SomeMethod(int32)//Pushes the method pointer referenced by SomeMethod. 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0008:  newobj     instance void class Artech.LambdaExpression.Function`2<int32,bool>::.ctor(object,

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

                                                                                                 native int)//Initializer a Artech.LambdaExpression.Function delegate instance.

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_000d:  stsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::_namedMethodDelegate//Stores a static field: _namedMethodDelegate

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0012:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::_namedMethodDelegate//Pushes the static field(_namedMethodDelegate)  of an object Static .

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0017:  stloc.0   //Pop the first local variable 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0018:  ldloc.0   //Pushes the first local variable 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0019:  ldc.i4.s   20 //Pushes specified 8-bit value (20) as 32-bit 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_001b:  callvirt   instance !1 class Artech.LambdaExpression.Function`2<int32,bool>::Invoke(!0)//Calls virtual method of delegate instance. 

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0020:  pop

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0021:  ret

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

} // end of method Program::Main

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

對于Delegate,我無須再作深入的介紹,相信大家早已了如指掌。在這裡需要着重提出是,上面介紹的内容将是後續部分的基礎,通過後面的對Anonymous Method和Lambda expression介紹,你會發現它們生成的代碼結構和上面的是非常相似的。

二、  Anonymous Method Delegate

Anonymous Method是C# 2.0引入的一個非常好用的功能。通過Anonymous Method,我們可以Delegate的實作直接以Inline的方式放入Delegate對象使用的位置,而無須再繁瑣地建立一個Delegate,并通過定義在某個Class中具有相同申明的Method來事例化這個Delegate Instance,最後才将這個delegate instance傳入需要調用的Method。

我們現在通過Anonymous Method來簡化上面的代碼。

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            Function<int, bool> function2 = delegate(int args)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            {

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

                return args > 0;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            };

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            function2(20);   

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

[CompilerGenerated]

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

private static Function<int, bool> <>9__CachedAnonymousMethodDelegate1;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

private static bool <Main>b__0(int args)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

    return (args > 0);

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

是不是我我們上面一節定義的_namedMethodDelegate和SomeMethod這個兩個靜态成員一樣?  

我們進一步分析Main Method的IL。

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  // Code size       43 (0x2b)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function2)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0001:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1'

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0006:  brtrue.s   IL_001b

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0008:  ldnull

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0009:  ldftn      bool Artech.LambdaExpression.Program::'<Main>b__0'(int32)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_000f:  newobj     instance void class Artech.LambdaExpression.Function`2<int32,bool>::.ctor(object,

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

                                                                                                 native int)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0014:  stsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1'

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0019:  br.s       IL_001b

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_001b:  ldsfld     class Artech.LambdaExpression.Function`2<int32,bool> Artech.LambdaExpression.Program::'<>9__CachedAnonymousMethodDelegate1'

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0020:  stloc.0

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0021:  ldloc.0

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0022:  ldc.i4.s   20

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0024:  callvirt   instance !1 class Artech.LambdaExpression.Function`2<int32,bool>::Invoke(!0)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_0029:  pop

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  IL_002a:  ret

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

和我們上面一節的IL對比,是否出奇地相似。所用我們可以說,我們在第一節中Named Delegate和Anonymous Method Delegate是等效的。

接下來我們通過Lambda Expression實作上面的功能。

三、 Lambda Expression

下面是通過Lambda Expression實作上面相同功能的Code:

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            Function<int, bool> function3 = x => x > 0;

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

            function3(20);

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

我們進一步來看看Main Method的IL。

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

  .locals init ([0] class Artech.LambdaExpression.Function`2<int32,bool> function3)

[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression

和上面通過

Anonymous Method Delegate實作的時候完全是一樣的。

四、Conclusion 

現在我們可以得出結論了,Lambda Expression本質上是一個Anonymous Method Delegate,這個Delegate的匿名性僅僅針對Programming language而言,編譯器會為它生成一個Named delegate和一個它指向的Method。這個兩個額外生成的對象作為使用Anonymous Method Delegate對應的Class的Static Method而存在。從本質上講和一般的Delegate并沒有本質的差別。是以上面我們分别通過Named delegate、Anonymous method delegate和Lambda Expression實作的3個方式是等效的。

C# 3.x相關内容:

<a href="http://www.cnblogs.com/artech/archive/2007/07/15/818980.html">[原創]深入了解C# 3.x的新特性(1):Anonymous Type</a>

<a href="http://www.cnblogs.com/artech/archive/2007/07/18/821881.html">[原創]深入了解C# 3.x的新特性(2):Extension Method - Part I</a>

<a href="http://www.cnblogs.com/artech/archive/2007/07/19/823847.html">[原創]深入了解C# 3.x的新特性(2):Extension Method - Part II</a>

<a href="http://www.cnblogs.com/artech/archive/2007/08/22/865247.html">[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression</a>

<a href="http://www.cnblogs.com/artech/archive/2007/09/30/912166.html">[原創]深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2007/08/22/865247.html" target="_blank">原文連結</a>

繼續閱讀