简体   繁体   English

在运行时更改表达式树

[英]Changing expression tree at run time

I'm new to C# expressions trees. 我是C#表达式树的新手。

I've an expression tree being passed to a method as below: 我将表达式树传递给以下方法:

private void MyMethod(System.Linq.Expressions.Expression exp, string param)

I need to be able to tweak this exp and add two AND clauses based on the param value at runtime. 我需要能够调整此exp并在运行时基于参数值添加两个AND子句。 How do I achieve this please? 请问我该如何实现?

An example to call this method is: 调用此方法的示例是:

var temp= MyOtherMethod(cellValue.ExpressionObj, columnName);

Thanks. 谢谢。

You should take a look at ExpressionVisitor class . 您应该看一下ExpressionVisitor类

Good example how to use it can be found in Dissecting Linq Expression Trees - Part 2 blog post. 在“ 剖析Linq表达式树-第2部分”博客文章中可以找到如何使用它的好例子。

Expressions are immutable and you need to return new expression back to caller to use the altered one. 表达式是不可变的,您需要将新表达式返回给调用方以使用更改后的表达式。

Long story short: 长话短说:

private Expression MyMethod(Expression<MyClass> exp, string param) {
    if(param == "something") {
        var visitor = new CustomVisitor(); /// You should implement one based on your needs
        return visitor.Visit(exp);
    }
}

EDIT: 编辑:

public class AndAlsoVisitor : ExpressionVisitor {
    protected override Expression VisitLambda<T>(Expression<T> node) {
        // Make it lambda expression
        var lambda = node as LambdaExpression;

        // This should never happen
        if (node != null) {
            // Create property access 
            var lengthAccess = Expression.MakeMemberAccess(
                lambda.Parameters[0],
                lambda.Parameters[0].Type.GetProperty("Length")
            );

            // Create p.Length >= 10
            var cond1 = Expression.LessThanOrEqual(lengthAccess, Expression.Constant(10));
            // Create p.Length >= 3
            var cond2 = Expression.GreaterThanOrEqual(lengthAccess, Expression.Constant(3));
            // Create p.Length >= 10 && p.Length >= 3
            var merged = Expression.AndAlso(cond1, cond2);
            // Merge old expression with new one we have created
            var final = Expression.AndAlso(lambda.Body, merged);
            // Create lambda expression
            var result = Expression.Lambda(final, lambda.Parameters);

            // Return result
            return result;
        }

        return null;
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM