• 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 }

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

  • 相关阅读:
    Sobel算子 (转)
    由矩阵运算来看初等矩阵的左乘右乘所影响到矩阵的行列变换的本质(转)
    矩阵的迹(转)
    深度神经网络识别图形图像的基本原理(转)
    图解卷积神经网络(二)(转)
    Matlab 的reshape函数(转)
    iOS关键词weak和assign的区别
    网络层HTPPS和HTTP的概念与区别
    iOS开发之#impor与#include的区别
    iOS制作自己的Framework框架
  • 原文地址:https://www.cnblogs.com/meilibao/p/2681338.html
Copyright © 2020-2023  润新知