Heim > Backend-Entwicklung > C++ > Wie kombiniere ich zwei Expressionsobjekte mit logischen Operatoren?

Wie kombiniere ich zwei Expressionsobjekte mit logischen Operatoren?

Barbara Streisand
Freigeben: 2025-01-31 05:41:09
Original
381 Leute haben es durchsucht

In diesem Artikel werden Methoden zur Kombination von zwei Expression<Func<bool>> -Objekte unter Verwendung von logischen Operatoren in C#untersucht. Direkt mit AND oder OR zu verwenden, ist nicht möglich; Stattdessen werden Expression.AndAlso, OrElse und Not beschäftigt. Die Komplexität nimmt zu, wenn die Ausdrücke unterschiedliche Parameter verwenden. Es werden drei Lösungen vorgestellt:

How to Combine Two Expression Objects Using Logical Operators?

kombiniert zwei boolesche Ausdrücke

Die Herausforderung liegt in der Kombination von zwei Expression<Func<bool>> -Objekte mit logischen und oder oder nicht. Ein einfacher Ansatz wie expr1 AND expr2 ist ungültig.

Lösungen

Mehrere Methoden sprechen dies an:

Methode 1: Verwenden Sie Invoke

Diese Methode verwendet die Methode Invoke, um jeden Ausdruck in einem gemeinsamen Parameterkontext auszuführen.

static Expression<Func<bool>> AndAlso<T>(
    this Expression<Func<bool>> left,
    Expression<Func<bool>> right)
{
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.AndAlso(
            Expression.Invoke(left, param),
            Expression.Invoke(right, param)
        );
    var lambda = Expression.Lambda<Func<bool>>(body, param);
    return lambda;
}
Nach dem Login kopieren

Methode 2: Parameterersatz (bedingt)

Dieser Ansatz überprüft, ob die Ausdrücke denselben Parameter teilen. Wenn ja, wird ein einfacheres AndAlso verwendet. Ansonsten ruft es den zweiten Ausdruck mit dem Parameter aus dem ersten auf.

static Expression<Func<bool>> AndAlso<T>(
    this Expression<Func<bool>> expr1,
    Expression<Func<bool>> expr2)
{
    ParameterExpression param = expr1.Parameters[0];
    if (ReferenceEquals(param, expr2.Parameters[0]))
    {
        return Expression.Lambda<Func<bool>>(
            Expression.AndAlso(expr1.Body, expr2.Body), param);
    }
    return Expression.Lambda<Func<bool>>(
        Expression.AndAlso(
            expr1.Body,
            Expression.Invoke(expr2, param)), param);
}
Nach dem Login kopieren

Methode 3: ExpressionVisitor

Diese ausgefeilte Methode verwendet ein ExpressionVisitor, um die Parameter in einem Ausdruck systematisch zu ersetzen, um den anderen zu entsprechen, bevor AndAlso

angewendet wird.
public static Expression<Func<bool>> AndAlso<T>(
    this Expression<Func<bool>> expr1,
    Expression<Func<bool>> expr2)
{
    var parameter = Expression.Parameter(typeof(T));

    var leftVisitor = new ReplaceExpressionVisitor(expr1.Parameters[0], parameter);
    var left = leftVisitor.Visit(expr1.Body);

    var rightVisitor = new ReplaceExpressionVisitor(expr2.Parameters[0], parameter);
    var right = rightVisitor.Visit(expr2.Body);

    return Expression.Lambda<Func<bool>>(
        Expression.AndAlso(left, right), parameter);
}

private class ReplaceExpressionVisitor : ExpressionVisitor
{
    private readonly Expression _oldValue;
    private readonly Expression _newValue;

    public ReplaceExpressionVisitor(Expression oldValue, Expression newValue)
    {
        _oldValue = oldValue;
        _newValue = newValue;
    }

    public override Expression Visit(Expression node)
    {
        if (node == _oldValue)
            return _newValue;
        return base.Visit(node);
    }
}
Nach dem Login kopieren

Die Auswahl der Methode hängt von der Komplexität Ihrer Ausdrücke und der Notwendigkeit einer optimierten Leistung ab. Methode 1 ist unkompliziert, Methode 2 bietet eine Leistungsverbesserung, wenn die Parameter übereinstimmen, und die Methode 3 bietet eine robuste Lösung für den Umgang mit unterschiedlichen Parametern.

Das obige ist der detaillierte Inhalt vonWie kombiniere ich zwei Expressionsobjekte mit logischen Operatoren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Neueste Artikel des Autors
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage