Rumah >pembangunan bahagian belakang >C++ >Bagaimana menggabungkan dua objek ekspresi menggunakan pengendali logik?
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>pilihan kaedah bergantung kepada kerumitan ekspresi anda dan keperluan untuk prestasi yang dioptimumkan. Kaedah 1 adalah mudah, Kaedah 2 menawarkan peningkatan prestasi apabila parameter sepadan, dan Kaedah 3 menyediakan penyelesaian yang mantap untuk mengendalikan parameter yang berbeza.
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!