zoukankan      html  css  js  c++  java
  • LINQ表达式树3

    表达式目录树与委托

    大家可能经常看到如下这样的语言,其中第一句是直接用Lambda表达式来初始化了Func委托,而第二句则使用Lambda表达式来构造了一个表达式目录树,它们之间的区别是什么呢?

    static void Main(string[] args)
    {
        Func<int, int, int> lambda = (a, b) => a + b * 2;
        Expression<Func<int, int, int>> expression = (a, b) => a + b * 2;
    } 

    其实看一下IL就很明显,其中第一句直接将Lambda表达式直接编译成了IL,如下代码所示:

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      .maxstack  3
      .locals init ([0] class [System.Core]System.Func`3<int32,int32,int32> 
    lambda) IL_0000: nop IL_0001: ldsfld class [System.Core]System.Func`3<int32,int32,int32> TerryLee.LinqToLiveSearch.Program::
    'CS$<>9__CachedAnonymousMethodDelegate1' IL_0006: brtrue.s IL_001b IL_0008: ldnull IL_0009: ldftn int32 TerryLee.LinqToLiveSearch.Program::
    '<Main>b__0'(int32,int32) IL_000f: newobj instance void class [System.Core]System.Func`3
    <int32,int32,int32>::.ctor(object, native int) IL_0014: stsfld class [System.Core]System.Func`3<int32,int32,int32> TerryLee.LinqToLiveSearch.Program::
    'CS$<>9__CachedAnonymousMethodDelegate1' IL_0019: br.s IL_001b IL_001b: ldsfld class [System.Core]System.Func`3<int32,int32,int32> TerryLee.LinqToLiveSearch.Program::
    'CS$<>9__CachedAnonymousMethodDelegate1' IL_0020: stloc.0 IL_0021: ret }

    而第二句,由于告诉编译器是一个表达式目录树,所以编译器会分析该Lambda表达式,并生成表示该Lambda表达式的表达式目录树,即它与我们手工创建表达式目录树所生成的IL是一致的,如下代码所示,此处为了节省空间省略掉了部分代码:

    .method private hidebysig static void  Main(string[] args) cil managed
    {
      .entrypoint
      .maxstack  4
      .locals init ([0] class [System.Core]System.Linq.Expressions.Expression`1<
              class [System.Core]System.Func`3<int32,int32,int32>> expression,
        [1] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0000,
        [2] class [System.Core]System.Linq.Expressions.ParameterExpression CS$0$0001,
        [3] class [System.Core]System.Linq.Expressions.ParameterExpression[] CS$0$0002)
      IL_0000:  nop
      IL_0001:  ldtoken    [mscorlib]System.Int32
      IL_0006:  call       class [mscorlib]System.Type [mscorlib]System.Type::
    GetTypeFromHandle(...) IL_000b: ldstr "a" IL_0010: call class [System.Core]System.Linq.Expressions.ParameterExpression [System.Core]System.Linq.Expressions.Expression::Parameter( class [mscorlib]System.Type, IL_0038: call class [mscorlib]System.Type [mscorlib]System.Type::
    GetTypeFromHandle() IL_003d: call class [System.Core]System.Linq.Expressions.ConstantExpression [System.Core]System.Linq.Expressions.Expression::Constant(object, class [mscorlib]System.Type) IL_0042: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::
    Multiply(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression) IL_0047: call class [System.Core]System.Linq.Expressions.BinaryExpression [System.Core]System.Linq.Expressions.Expression::
    Add(class [System.Core]System.Linq.Expressions.Expression, class [System.Core]System.Linq.Expressions.Expression) IL_004c: ldc.i4.2 IL_004d: newarr [System.Core]System.Linq.Expressions.ParameterExpression }

    现在相信大家都看明白了,这里讲解它们的区别主要是为了加深大家对于表达式目录树的区别。

  • 相关阅读:
    Windows 2008 R2 远程桌面服务(八)远程桌面服务器安全设置
    从硬盘上安装SQLServer2005的问题
    在 Windows server 2008 下计划任务无法正常执行bat批处理文件
    两部搞定windows server 2008 R2 中IE8的增强安全配置功能
    Microsoft SQL Server 2005 Service Pack 4 RTM
    学习地址
    Windows 2008 远程桌面如何设置两个用户共享一个会话
    Windows Server 2008 启用无线网卡
    远程桌面连接指定会话(Session)
    固定宽度弹性布局(以适应各种各辨率)
  • 原文地址:https://www.cnblogs.com/meilibao/p/2681338.html
Copyright © 2011-2022 走看看