天天看点

[原创]深入理解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>