开发者

How to Combine two lambdas [duplicate]

开发者 https://www.devze.com 2023-03-20 22:27 出处:网络
This question already has answers here: Closed 11 years ago. Possible Duplicate: com开发者_JS百科bining two lamba expressions in c#
This question already has answers here: Closed 11 years ago.

Possible Duplicate:

com开发者_JS百科bining two lamba expressions in c#

I have two following expressions:

Expression<Func<string, bool>> expr1 = s => s.Length == 5;
Expression<Func<string, bool>> expr2 = s => s == "someString";

Now I need to combine them with OR. Something like this:

Expression.Or(expr1, expr2)

Is there any way to make this similar to above code way like:

expr1 || expr2

I understand in this example I can just combine it in the first place:

Expression<Func<string, bool>> expr = s => s.Length == 5 || s == "someString"

but I can't do it in my real code as I get expr1 and expr2 as arguments to the method.


To complete Eric's answer, using the new ExpressionVisitor introduced in .NET 4 rather than a custom rewriter:

internal class ParameterReplacer : ExpressionVisitor {
    private readonly ParameterExpression _parameter;

    protected override Expression VisitParameter(ParameterExpression node) {
        return base.VisitParameter(_parameter);
    }

    internal ParameterReplacer(ParameterExpression parameter) {
        _parameter = parameter;
    }
}

class Program {

    static void Main(string[] args) {
        Expression<Func<string, bool>> expr1 = s => s.Length == 5;
        Expression<Func<string, bool>> expr2 = s => s == "someString";
        var paramExpr = Expression.Parameter(typeof(string));
        var exprBody = Expression.Or(expr1.Body, expr2.Body);
        exprBody = (BinaryExpression) new ParameterReplacer(paramExpr).Visit(exprBody);
        var finalExpr = Expression.Lambda<Func<string, bool>>(exprBody, paramExpr);
    }

}


The problem is that the "s" parameters in each lambda have the same name and same type, but they are different parameters. Parameters have reference identity, not value identity. Simply combining the two bodies of the existing expression trees into a third expression tree effectively makes:

s => s1.Length == 5 || s2 == "somestring"

which doesn't make any sense. What you want to do is write a visitor that does a search-and-replace of the parameter s with a new parameter that you will then use as the parameter to the new lambda expression.

See this related question for more details:

Combining two lambda expressions in c#

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号