这篇文章主要介绍“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()正确的使用方法”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注亿速云网站,小编会继续努力为大家带来更多实用的文章!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。