4

我决定花一些黄金时间来学习更多关于表达式的知识。我正在尝试一个非常简单的练习,即添加两个数字。我遇到了一个很难搜索的异常。

这是我的代码

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”

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

4

3 回答 3

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);
于 2012-09-05T12:36:04.933 回答
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);
于 2012-09-05T12:29:24.107 回答
1

您需要分解addExpr的主体,或者最好只是从头开始编写,Expression.Add(p1,p2)而不是addExpr.

于 2012-09-05T12:32:59.550 回答