Maison >développement back-end >C++ >Comment combiner deux objets d'expression à l'aide d'opérateurs logiques?
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:
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.
<code class="language-csharp">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; }</code>
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.
<code class="language-csharp">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); }</code>
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
.
<code class="language-csharp">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); } }</code>
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!