Maison > développement back-end > C++ > Comment puis-je combiner deux expressions d'expression en utilisant et, ou, et non des opérateurs en C #?

Comment puis-je combiner deux expressions d'expression en utilisant et, ou, et non des opérateurs en C #?

DDD
Libérer: 2025-01-31 05:56:10
original
941 Les gens l'ont consulté

Cet article montre comment combiner deux expressions C # de type Expression<Func<bool>> en utilisant logique et, ou, et non opérateurs. L'utilisation directe d'opérateurs comme expr1 AND expr2 est incorrect en raison de décalages de paramètres. Plusieurs approches sont présentées, chacune abordant différents scénarios.

Méthode 1: combinaison simple (paramètres identiques)

Si les deux expressions utilisent le même paramètre, une approche simple consiste à utiliser Expression.AndAlso ou Expression.OrElse directement sur les corps d'expression:

<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
Copier après la connexion

La négation est tout aussi simple:

<code class="language-csharp">static Expression<Func<bool>> Not<T>(this Expression<Func<bool>> expr)
{
    return Expression.Lambda<Func<bool>>(Expression.Not(expr.Body), expr.Parameters[0]);
}</code>
Copier après la connexion

Méthode 2: combinant des expressions avec différents paramètres en utilisant invoquer

Lorsque les expressions ont des paramètres différents, la méthode Invoke peut être utilisée pour créer une nouvelle expression de lambda avec un 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>
Copier après la connexion

OrElse serait similaire, en remplaçant AndAlso par OrElse.

Méthode 3: combinaison optimisée (gère les paramètres identiques et différents)

Cette méthode choisit intelligemment l'approche plus simple si les paramètres sont les mêmes, autrement utilise Invoke:

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

Méthode 4: approche EF-SAFE Utilisation de l'expressionVisitor (.NET 4.0 et ultérieurement)

Pour la compatibilité du cadre d'entité, un ExpressionVisitor fournit une solution robuste:

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

Cette méthode remplace les références de paramètres dans les expressions pour assurer la compatibilité avec divers fournisseurs LINQ. Le choix de la méthode dépend des besoins et du contexte spécifiques de votre application, en particulier le fournisseur LINQ utilisé et si la cohérence des paramètres est garantie. L'approche ExpressionVisitor offre la solution la plus robuste pour les scénarios complexes et l'intégration du cadre d'entité.

How Can I Combine Two Expression Expressions Using AND, OR, and NOT Operators in C#?

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!

source:php.cn
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal