Artikel ini meneroka kaedah untuk menggabungkan dua objek Expression<Func<bool>>
menggunakan pengendali logik dalam C#. Secara langsung menggunakan AND
atau OR
tidak mungkin; Sebaliknya, Expression.AndAlso
, OrElse
, dan Not
digunakan. Kerumitan meningkat apabila ungkapan menggunakan parameter yang berbeza. Tiga penyelesaian dibentangkan:
menggabungkan dua ekspresi boolean
Cabaran terletak pada menggabungkan dua objek menggunakan logik dan, atau, atau tidak. Pendekatan mudah seperti Expression<Func<bool>>
tidak sah. expr1 AND expr2
Penyelesaian
Beberapa kaedah menangani ini:
Kaedah 1: Menggunakan Invoke
untuk melaksanakan setiap ungkapan dalam konteks parameter yang sama. 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>
kaedah 2: penggantian parameter (bersyarat)
Pendekatan ini memeriksa jika ungkapan berkongsi parameter yang sama. Jika ya, mudah digunakan. Jika tidak, ia memanggil ungkapan kedua menggunakan parameter dari yang pertama. AndAlso
<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>
Kaedah 3: ExpressionVisitor
untuk menggantikan parameter secara sistematik dalam satu ungkapan untuk memadankan yang lain sebelum memohon ExpressionVisitor
. 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>
Atas ialah kandungan terperinci Bagaimana menggabungkan dua objek ekspresi menggunakan pengendali logik?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!