Maison > développement back-end > C++ > Comment combiner deux objets d'expression à l'aide d'opérateurs logiques?

Comment combiner deux objets d'expression à l'aide d'opérateurs logiques?

Barbara Streisand
Libérer: 2025-01-31 05:41:09
original
381 Les gens l'ont consulté

Cet article explore les méthodes pour combiner deux objets Expression<Func<bool>> utilisant des opérateurs logiques en C #. Directement à l'aide de AND ou OR n'est pas possible; Au lieu de cela, Expression.AndAlso, OrElse et Not sont utilisés. La complexité augmente lorsque les expressions utilisent différents paramètres. Trois solutions sont présentées:

How to Combine Two Expression Objects Using Logical Operators?

combinant deux expressions booléennes

Le défi réside dans la combinaison de deux objets Expression<Func<bool>> utilisant logique et, ou, ou non. Une approche simple comme expr1 AND expr2 est invalide.

Solutions

Plusieurs méthodes abordent ceci:

Méthode 1: Utilisation de Invoke

Cette méthode utilise la méthode Invoke pour exécuter chaque expression dans un contexte de paramètre commun.

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;
}
Copier après la connexion

Méthode 2: remplacement des paramètres (conditionnel)

Cette approche vérifie si les expressions partagent le même paramètre. Si c'est le cas, un AndAlso plus simple est utilisé. Sinon, il invoque la deuxième expression en utilisant le paramètre du premier.

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);
}
Copier après la connexion

Méthode 3: ExpressionVisitor

Cette méthode sophistiquée utilise un ExpressionVisitor pour remplacer systématiquement les paramètres d'une expression pour correspondre à l'autre avant d'appliquer AndAlso.

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);
    }
}
Copier après la connexion

Le choix de la méthode dépend de la complexité de vos expressions et du besoin de performances optimisées. La méthode 1 est simple, la méthode 2 offre une amélioration des performances lorsque les paramètres correspondent, et la méthode 3 fournit une solution robuste pour gérer les paramètres disparates.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal