表达......我做错了什么?

时间:2012-09-05 12:26:56

标签: c# expression argumentexception

我决定花些时间来学习更多关于表达式的知识。我正在尝试一个非常简单的练习,即添加两个数字。我遇到了一个例外,这个例外被证明是非常棘手的。

这是我的代码

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'

在上面指出的行。我做错了什么?

3 个答案:

答案 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);

您当前的代码需要intExpression<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