在C#表達式中組合邏輯表達式
當您有兩個Expression<Func<bool>>
類型的表達式時,您可能需要使用邏輯運算符(如AND、OR或NOT)來組合它們。本文探討實現此目標的各種方法。
相同參數實例
如果兩個表達式使用相同的ParameterExpression
,則組合很簡單:
<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body); var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
這也適用於否定單個操作:
<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>
不同的參數實例
如果表達式使用不同的參數實例,您可以使用Invoke
進行組合:
<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>
此方法也適用於OrElse
和Not
。
通用方法
為了處理這兩種情況,一種通用方法可以檢測哪些參數匹配並選擇合適的組合方法:
<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>
EF兼容性
從.NET 4.0開始,ExpressionVisitor
提供了一種構建EF兼容表達式的機制:
<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>
通過選擇與您的特定場景相符的方法,您可以有效地組合Expression<Func<bool>>
實例中的邏輯表達式。
以上是如何將邏輯表達式組合在C#表達中?的詳細內容。更多資訊請關注PHP中文網其他相關文章!