使用BinaryExpression作为参数添加表达式

时间:2019-09-17 10:21:52

标签: c# expression-trees

如何使用Expression执行嵌套加法运算? Expression.Lambda<>期望的参数类型为ParameterExpression,但是我的参数之一是加法的结果,因此其类型为BinaryExpression。它们不是彼此派生的,所以我无法转换它们,也找不到任何方法将BinaryExpression转换为ParameterExpression

示例:

var left = Expression.Parameter(typeof(int));
var rightLeft = Expression.Parameter(typeof(int));
var rightRight = Expression.Parameter(typeof(int));
var right = Expression.Multiply(rightLeft, rightRight);

var add = Expression.Add(left, right);

var multiplyResult = Expression.Lambda<Func<int, int, int>>(right, rightLeft, rightRight).Compile()(5, 3);
var result = Expression.Lambda<Func<int, int, int>>(add, left, Expression.Parameter(typeof(int))).Compile();

最后一行抛出

  

System.InvalidOperationException:类型为“ System.Int32”的“变量”   从范围“”引用,但未定义”

表达式应编译为:

var result = left + (rightLeft * rightRight);

1 个答案:

答案 0 :(得分:1)

您可以只调用一次Compile,然后在其他二进制表达式中引用乘法结果。尝试以下代码:

var inputType = typeof(int);

var left = Expression.Parameter(inputType, "left");
var rightLeft = Expression.Parameter(inputType, "rightLeft");
var rightRight = Expression.Parameter(inputType, "rightRight");

var multiply = Expression.Multiply(rightLeft, rightRight);
var add = Expression.Add(left, multiply);

var lambda = Expression.Lambda<Func<int, int, int, int>>(add, left, rightLeft, rightRight);
Console.WriteLine(lambda.ToString()); // will print "(left, rightLeft, rightRight) => (left + (rightLeft * rightRight))"

var result = lambda.Compile().Invoke(1, 2, 3);

Console.WriteLine(result); // will print "7"