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 }

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

  • 相关阅读:
    opencv3.2.0形态学滤波之腐蚀
    Ubuntu下卸载QT5.7.1再重装
    opencv3.2.0形态学滤波之膨胀
    Direct3D中的绘制
    绘制流水线
    初始化Direct3D
    VS2012添加对DirectX SDK中需要文件的引用
    ASCII,Unicode 和通用方式
    对话框访问的7种方式【孙鑫老师教程】
    函数指针
  • 原文地址:https://www.cnblogs.com/meilibao/p/2681338.html
Copyright © 2011-2022 走看看