delegate、Lambda表达式、Func委托和Expression(TDelegate)表达式目录树

一、delegate

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

    class Program
    {
       const int num = 100;
       delegate bool delCompare(int a); //定义委托数据类型delCompare(传入int参数,返回bool类型的方法)
       static void Main(string[] args)
        {
            delCompare hander = DelegateMethod; //定义委托变量hander,给hander赋函数DelegateMethod
            hander(1); //运行委托hander,间接的调用运行DelegateMethod方法
        }

       public static bool DelegateMethod(int a)
       {
           return a > num;
       }
    }

其他方法:委托指向方法

delCompare hander=new delCompare(DelegateMethod);

Console.Write(hander(1));


用IL Disassemble查看


二、匿名委托

匿名委托即使用了匿名方法的委托,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查看


三、Lambda表达式

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

    class Program
    {
        const int num = 100;
        delegate bool delCompare(int a);//第1步:定义委托
       static void Main(string[] args)
        {
            delCompare del = a => a > num;//第2步:委托指向方法
        }
    }

        执行Lambda 表达式:

             del(1)


四、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;
        }
    }

封装方法:Func<int,bool> del = a=>a>num

执行方法:del(1)



五、Expression(TDelegate) :将强类型Lamda表达式表示为数据结构

表达式目录树以数据形式表示语言级别代码。数据存储在树形结构中。表达式目录树中的每个节点都表示一个表达式。以下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); //执行表达式
        }
    }


Expression<Func<int,bool>> exp =a=>a>num


查看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表达式中必须用到



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值