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:
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; }
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); }
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
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); } }
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!