我决定花些时间来学习更多关于表达式的知识。我正在尝试一个非常简单的练习,即添加两个数字。我遇到了一个例外,这个例外被证明是非常棘手的。
这是我的代码
Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda = Expression.Lambda<Func<int,int,int>>(addExpr, p1, p2); //<-here
var del = lambda.Compile();
var result = del(2,3); //expect 5
但这是抛出ArgumentException:类型'System.Func`3 [System.Int32,System.Int32,System.Int32]'的表达式不能用于返回类型'System.Int32'
在上面指出的行。我做错了什么?
答案 0 :(得分:4)
您需要使用表达式参数
将addExpr
包装在调用中
Expression<Func<int,int,int>> addExpr = (x, y) => x + y;
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var invokeExpression=Expression.Invoke(addExpr,p1,p2);
var lambda = Expression.Lambda<Func<int,int,int>>(invokeExpression,p1,p2);
var del = lambda.Compile();
var result=del(2,3);
调用是你输入p1到x和p2到y的方式,或者你可以把上面的内容写成
var p1 = Expression.Parameter(typeof(int), "p1");
var p2 = Expression.Parameter(typeof(int), "p2");
var lambda=Expresion.Lambda<Func<int,int,int>>(Expression.Add(p1,p2),p1,p2);
var del = lambda.Compile();
var result=del(2,3);
否则,您需要将表达式主体抓取到lambda中并传递表达式参数。
var lambda=Expresion.Lambda<Func<int,int,int>>(addExpr.Body,addExpr.Parameters);
答案 1 :(得分:2)
您的代码应为:
var lambda = Expression.Lambda<Func<Expression<Func<int, int, int>>, int, int>(addExpr, p1, p2);
您当前的代码需要int
和Expression<Func<int, int, int>>
传入。
<强>更新强>
实际上上面的内容不会编译,你需要这样做:
var lambda = Expression.Lambda<Func<int, int, int>>(Expression.Add(p1, p2), p1, p2);
答案 2 :(得分:1)
你需要分解addExpr
的身体,或者最好是从头开始写{ie} Expression.Add(p1,p2)
而不是addExpr
。