较之前一个版本,对于C# 3.xVB 9来说,LINQ是最具吸引力的。基本上很多的新的特性都是围绕着LINQ的实现来设计的。借助Extension Method,我们可以为LINQ定义一系列的Operator。通过Lambda Expression我们可以为LINQ编写更加简洁的查询。我们可以说这些新的特性成就了LINQ,也可以说这些新特性就是为了实现LINQ而产生,但是我们应该明白,对于这些新引入的特性,LINQ并非他们唯一的用武之地,在一般的编程中,我们也可以使用它们。

继上一章,介绍Extension Method之后,我们接着来介绍另一个重要的特性:Lambda Expression。在前面的两篇文章中,我一再在强调这样的一个概念:C# 3.x新引入的这些特性仅仅反映在Programming Language和相应的Compiler层面。通过编译生成的AssemblyIL和原来并没有本质的改变。从这个意义上讲,所有的这些其实是编译器给我们玩得障眼法而已。Lambda Expression也不例外, Lambda Expression就是一个Anonymous Delegate,无论是Named Delegate也好、Anonymous Delegate也好,其本质也就是一个Delegate

接下来,我将通过一个简单的Demonstration,由浅入深地分析Lambda Expression,看看编译器到底会编译生成怎样的额外的Code,他们的IL又是如何。

一、Named Delegate

在上面,我说了Lambda Expression本质上就是一个Delegate,我们先不直接来介绍Lambda Expression, 我们先来看看我们最为熟悉的Delegate的例子: 

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expressionusing 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
}

上面的例子很简单,先定一个Generic Delegate Function。在Program Class中定义一个StaticFunction字段_namedMethodDelegate和与之对应的MethodSomeMethod,判断输入的数字是否大于零。在Main中实例化_namedMethodDelegate,并调用它。

我们通过IL Disassembler这个Utility来看看Main方法的IL代码。为了让对IL Instruction不是很了解的读者更加容易地理解整个执行过程,我加了简单注释。对于那些希望进一步了解整个MSIL Instruction列表的读者,可以参考:MSIL Instruction Table

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression.method private hidebysig static void  Main() cil managed

对于Delegate,我无须再作深入的介绍,相信大家早已了如指掌。在这里需要着重提出是,上面介绍的内容将是后续部分的基础,通过后面的对Anonymous MethodLambda expression介绍,你会发现它们生成的代码结构和上面的是非常相似的。

二、  Anonymous Method Delegate

Anonymous MethodC# 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 Expressionusing 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

我们通过Reflector分析编译生成的Assembly,我们发现它具有下面的结构。进一步分析Program Class,我们发现它多了两个额外的Static成员:<>9__CachedAnonymousMethodDelegate1<Main>b__0。这是编译器的功劳。

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

下面分别是<>9__CachedAnonymousMethodDelegate1<Main>b__0的定义:

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression[CompilerGenerated]

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression
private static Function<intbool> <>9__CachedAnonymousMethodDelegate1;

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression[CompilerGenerated]

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression
private static bool <Main>b__0(int args)


是不是我我们上面一节定义的_namedMethodDelegateSomeMethod这个两个静态成员一样?  

我们进一步分析Main MethodIL

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression.method private hidebysig static void  Main() cil managed

和我们上面一节的IL对比,是否出奇地相似。所用我们可以说,我们在第一节中Named DelegateAnonymous Method Delegate是等效的。

接下来我们通过Lambda Expression实现上面的功能。

三、 Lambda Expression

下面是通过Lambda Expression实现上面相同功能的Code

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expressionusing 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

我们通过Reflector分析编译生成的Assembly,我们发现它和通过Anonymous Method Delegate实现的完全一样:Program Class,我们发现它多了两个额外的Static成员,它们的名称都完全一样:<>9__CachedAnonymousMethodDelegate1<Main>b__0

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

这两个Static Member<>9__CachedAnonymousMethodDelegate1<Main>b__0的定义也于我们通过Anonymous Method Delegate实现时一模一样:

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression[CompilerGenerated]

[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression
private static Function<intbool> <>9__CachedAnonymousMethodDelegate1;

[原创]深入理解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 bool <Main>b__0(int args)



我们进一步来看看Main MethodIL。
 
[原创]深入理解C# 3.x的新特性(3):从Delegate、Anonymous Method到Lambda Expression.method private hidebysig static void  Main() cil managed

和上面通过

Anonymous Method Delegate实现的时候完全是一样的。

四、Conclusion
 

 

现在我们可以得出结论了,Lambda Expression本质上是一个Anonymous Method Delegate,这个Delegate的匿名性仅仅针对Programming language而言,编译器会为它生成一个Named delegate和一个它指向的Method。这个两个额外生成的对象作为使用Anonymous Method Delegate对应的ClassStatic Method而存在。从本质上讲和一般的Delegate并没有本质的区别。所以上面我们分别通过Named delegateAnonymous method delegateLambda Expression实现的3个方式是等效的。

C# 3.x相关内容:
[原创]深入理解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

相关文章:

  • 2022-01-03
  • 2022-01-28
  • 2021-11-12
  • 2021-12-05
  • 2022-12-23
  • 2021-10-16
猜你喜欢
  • 2021-09-23
  • 2021-09-12
  • 2021-06-21
  • 2021-09-25
  • 2021-10-10
  • 2022-12-23
相关资源
相似解决方案