Wie man zwei lambdas kombiniert

.net c# expression-trees

Frage

Mögliche Duplikate:
Kombination von zwei Lamba-Ausdrücken in c #

Ich habe zwei folgende Ausdrücke:

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

Jetzt muss ich sie mit OR kombinieren. Etwas wie das:

Expression.Or(expr1, expr2)

Gibt es eine Möglichkeit dies ähnlich wie oben beschrieben zu machen:

expr1 || expr2

Ich verstehe in diesem Beispiel, dass ich es in erster Linie kombinieren kann:

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

aber ich kann es nicht in meinem echten Code tun, da ich Ausdruck1 und Ausdruck2 als Argumente für die Methode bekomme.

Akzeptierte Antwort

Um Erics Antwort zu vervollständigen, verwenden Sie den neuen ExpressionVisitor , der in .NET 4 eingeführt wurde, und nicht einen benutzerdefinierten 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);
    }

}

Beliebte Antwort

Das Problem ist, dass die "s" Parameter in jedem Lambda den gleichen Namen und den gleichen Typ haben, aber sie sind unterschiedliche Parameter. Parameter haben eine Referenzidentität , keine Wertidentität . Die Kombination der beiden Körper der existierenden Ausdrucksbäume in einen dritten Ausdrucksbaum macht effektiv:

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

was keinen Sinn ergibt. Sie möchten einen Besucher schreiben, der die Parameter s mit einem neuen Parameter sucht und ersetzt, den Sie dann als Parameter für den neuen Lambda-Ausdruck verwenden.

Weitere Informationen finden Sie in dieser verwandten Frage:

Kombinieren von zwei Lambda-Ausdrücken in c #



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow