如何将表达式树编译成可调用的方法C#?

我有一个表达式树,我通过使用C#中的表达式类解析Xml来创建。 看到这个问题 。

我只在我的表达式树中添加,减去,除以,乘,参数和和。 有没有办法将此ExpressionTree转换为可调用方法? …还是我必须手动发射IL?

亲切的问候,

以下是两种方法的示例。 如果我遗漏了某些内容,或者您​​想了解更多信息,请告诉我。

static void Main() { // try to do "x + (3 * x)" var single = BuildSingle(); var composite = BuildComposite(); Console.WriteLine("{0} vs {1}", single(13.2M), composite(13.2M)); } // utility method to get the 3 as the correct type, since there is not always a "int x T" static Expression ConvertConstant(TSource value) { return Expression.Convert(Expression.Constant(value, typeof(TSource)), typeof(TDestination)); } // option 1: a single expression tree; this is the most efficient static Func BuildSingle() { var param = Expression.Parameter(typeof(T), "x"); Expression body = Expression.Add(param, Expression.Multiply( ConvertConstant(3), param)); var lambda = Expression.Lambda>(body, param); return lambda.Compile(); } // option 2: nested expression trees: static Func BuildComposite() { // step 1: do the multiply: var paramInner = Expression.Parameter(typeof(T), "inner"); Expression bodyInner = Expression.Multiply( ConvertConstant(3), paramInner); var lambdaInner = Expression.Lambda(bodyInner, paramInner); // step 2: do the add, invoking the existing tree var paramOuter = Expression.Parameter(typeof(T), "outer"); Expression bodyOuter = Expression.Add(paramOuter, Expression.Invoke(lambdaInner, paramOuter)); var lambdaOuter = Expression.Lambda>(bodyOuter, paramOuter); return lambdaOuter.Compile(); } 

就个人而言,我会瞄准第一种方法; 它既简单又有效。 这可能涉及将原始参数传递到整个嵌套代码堆栈中,但也就是这样。 我有一些代码采用“调用”方法(复合),并重新编写树作为第一种方法(单一) – 但它非常复杂和冗长。 但对Entity Framework(不支持Expression.Invoke)非常有用。

你需要创建一个lambda – 即

 var lambda = Expression.Lambda>(body, param); Func method = lambda.Compile(); int v = method(1.0); // test 

其中“body”是涉及ParameterExpression参数的表达式树(带浮点数,返回一个int)。

你也可以找到这个 , 这很有帮助。