当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何将表达式树编译成可调用的方法C#?》经验,为你挑选了2个好方法。

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

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

亲切的问候,



1> Marc Gravell..:

你需要创建一个lambda - 即

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

其中"body"是涉及ParameterExpressionparam的表达式树(使用float,返回int).

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



2> Marc Gravell..:

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

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)非常有用.

推荐阅读
贾志军
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有