MethodCallExpression和Expression.Compile()正确的使用方法

发布时间:2021-06-29 14:48:20 作者:chen
来源:亿速云 阅读:648

这篇文章主要介绍“MethodCallExpression和Expression.Compile()正确的使用方法”,在日常操作中,相信很多人在MethodCallExpression和Expression.Compile()正确的使用方法问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MethodCallExpression和Expression.Compile()正确的使用方法”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

            Expression<Func<int,int>> expmethod = ep=>ep+50;            
            //LambdaExpression lbda = Expression.Lambda<Func<int,int>>(expmethod.Body,Expression.Parameter(typeof(int)));
            //var lbdadel = lbda.Compile();
            //Console.WriteLine("Expression<Func<int,int>> expmethod = ep=>ep+50 = " + lbdadel.Invoke(4));//.DynamicInvoke(4));
            //结果运行时发现:
            //var lbdadel = lbda.Compile();这一句出现:System.InvalidoperationException类型的未经处理的异常在System.Core.dll中发生
            //其他信息:从作用域""引用了"System.Int32"类型的变量"ep",但该变量未定义

            //其实这样将Expression<Func<...>> exp = ep=>ep+50;这种表达式再用Expression.Lambda(...)创建Lambda表达式的做法是不正确的,
            //因为Expression<Func<...>> exp = ep=>ep+50 所定义的exp本来就是一个LambdaExpression,这个时候只能用LambdaExpression类
            //的Compile()直接进行编译才是正确的做法
            var lbdadel = expmethod.Compile();
            Console.WriteLine("Expression<Func<int,int>> expmethod = ep=>ep+50 = " + lbdadel.DynamicInvoke(4));

以上作法是针对Expression<Func/Action>> exp = exp=>xxxxxx;这种形式的表达式进行Compile()再进行调用从而得出结果值,如果是一个类中的方法,我有这个类的对象变量,如何通过表达式形式进行调用呢?

class ClassMethodCallExpression:IMethodCallExpression
    {

        public int methodfun(int arg) //接口中的方法的实现
        {
            return arg + 5;
        }
    }

IMethodCallExpression imce = new ClassMethodCallExpression();
            //Func<MethodCallExpression,int> exp = (ex=>ex.methodfun)
            //MethodInfo无法new出来对象,怎么创建一个MethodInfo呢???
            MethodInfo mi = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
            ConstantExpression ce = Expression.Constant("3");
            MethodCallExpression mce = Expression.Call(mi, ce);//针对静态方法
            Action a = Expression.Lambda<Action>(mce).Compile();  
            a();//也就是Console.WriteLine方法的执行

            MethodInfo mi2 = typeof(ClassMethodCallExpression).GetMethod("methodfun",new Type[]{typeof(int)});
            ConstantExpression ce2 = Expression.Constant(5);
            MethodCallExpression mce2 = Expression.Call(Expression.Constant(imce),mi2, ce2);//针对非静态方法
            //Expression.Call方法中,无Expression instance则表示将调用的是静态方法
            //当MehtodCallExpression准备调用实例方法时,可以通过Expression.Constant(实例对象变量)创建ConstantExpression,然后将这个ConstantExpression当作instance传参
            //具体以及更复杂的例子参考 https://blog.csdn.net/weixin_34402090/article/details/85786004
            // MethodCallExpression Expression.Call(Expression instance,MehtodInfo,params Expression[] arguments)或者
            //Expression.Call(MehtodInfo,params Expression[])
            var a2 = Expression.Lambda<Func<int>>(mce2).Compile();
            //MethodCallExpression使用步骤(如果是静态方法当然不需要目标对象变量)
            //1:定义好要用到的目标对象变量(因为最终要执行的方法在它所属的类中)
            //2:定义好要用到的参数表达式或常量表达式等
            //3:通过typeof(目标对象所在的类).GetMethod获得MethodInfo
            //4:利用Expression.Lambda<Action或Func>(MethodCallExpression).compile().Invoke或直接调用compile好的委托,注意:一定要用Action或Func,
            //也就是说不能Expression.Lambda(...),必须要用Expression.Lambda<Action/Func>形式
            Console.WriteLine("a2=" + a2());

到此,关于“MethodCallExpression和Expression.Compile()正确的使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!

推荐阅读:
  1. libc.so.6: cannot open shared object file
  2. c++音视频开发FFmpeg介绍与基础知识理解

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

上一篇:CSS Scoped的实现原理分析

下一篇:Android中怎么实现微信支付功能

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》