zoukankan      html  css  js  c++  java
  • delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树

    1.delegate

    MSDN:一种安全地封装方法的类型,它与 C 和 C++ 中的函数指针类似。与 C 中的函数指针不同,委托是面向对象的、类型安全的和保险的。委托的类型由委托的名称定义。

     
        class Program
        {
            const int num = 100;
            delegate bool delCompare(int a);
           static void Main(string[] args)
            {
                delCompare hander = DelegateMethod;
                hander(1);
            }
    
           public static bool DelegateMethod(int a)
           {
               return a > num;
           }
        }


    用IL Disassemble查看

    image_thumb[3]
    匿名委托:

    匿名委托即使用了匿名方法的委托,IL层中的代码中会为匿名函数生一个静态的函数,本次的代码中的函数名是:CS$<>9__CachedAnonymousMethodDelegate1

        class Program
        {
            const int num = 100;
            delegate bool delCompare(int a);
           static void Main(string[] args)
            {
                delCompare del = delegate(int a) { return a > num; };
            }
        }
    用IL Disassemble查看

    image_thumb[5]

    2.Lambda表达式

    使用Lambda表达式与上一个Demo中使用匿名函数生成的IL代码是完全一样的

        class Program
        {
            const int num = 100;
            delegate bool delCompare(int a);
           static void Main(string[] args)
            {
                delCompare del = a => a > num;
            }
        }


    image_thumb[7]

    3.Func<T1..TResult>

    使用Func<T1…TResult>中的Demo中,在IL层代中有所不同。代码中没有用到delegate,相当于在Main方法中直接调用了一个静态方法。理论上Func<T1…TResult>比delegate在时间和空间的效率都要高

        class Program
        {
            const int num = 100;
            //delegate bool delCompare(int a);
           static void Main(string[] args)
            {
                Func<int, bool> del = a => a > num;
            }
        }


    image_thumb[9]

    4.Expression(TDelegate)

    表达式目录树以数据形式表示语言级别代码。数据存储在树形结构中。表达式目录树中的每个节点都表示一个表达式。以下Demo中IL层的代码中并未生成任何静态函数。

        class Program
        {
            const int num = 100;
            //delegate bool delCompare(int a);
           static void Main(string[] args)
            {
                Expression<Func<int, bool>> exp = a => a > num; //生在表达式
                Func<int,bool> fun = exp.Compile(); //编辑表达式
                fun(1); //执行表达式
            }
        }

    image_thumb[11]

    查看Main函数,在IL层代码中会对Expression动太编译生成实例!0,再通过Invoke(!0)调用方法

    IL_0045: callvirt instance !0 class [System.Core]System.Linq.Expressions.Expression`1<class [mscorlib]System.Func`2<int32,bool>>::Compile()
    IL_004a: stloc.1
    IL_004b: ldloc.1
    IL_004c: ldc.i4.1
    IL_004d: callvirt instance !1 class [mscorlib]System.Func`2<int32,bool>::Invoke(!0)
    IL_0052: pop
    IL_0053: ret

    总结:

    匿名delegate和Lambda表达式本质是一样的,Func<T1..TResult>委托与delegate不同,它没有委托的异常调用等特性,在IL层生成的代码不同,执行方式不同。Expression(TDelegate)则是语言级别的,用于动太生成表达式,理论上Expression(TDelegate)效率最差。但在Linq表达式中必须用到。

    *************转摘:https://www.cnblogs.com/xuf22/archive/2011/09/21/2184351.html

  • 相关阅读:
    windows num lock 自动关闭 相关注册表项
    kettle之连接达梦
    kettle之连接mysql
    kettle之mysql数据导入mongo
    docker解决mqtt.fx连接不上emqx问题
    linux下mongo数据导出导入
    记录一次docker现场环境部署
    拓端tecdat|python用支持向量机回归(SVR)模型分析用电量预测电力消费
    拓端tecdat|R语言深度学习Keras循环神经网络(RNN)模型预测多输出变量时间序列
    拓端tecdat|R语言绘制圈图、环形热图可视化基因组实战:展示基因数据比较
  • 原文地址:https://www.cnblogs.com/linybo/p/13353518.html
Copyright © 2011-2022 走看看