Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah saya boleh menggabungkan dua ekspresi ekspresi menggunakan dan, atau, dan bukan pengendali di C#?
Artikel ini menunjukkan cara menggabungkan dua ekspresi C# jenis Expression<Func<bool>>
menggunakan logik dan, atau, dan bukan pengendali. Secara langsung menggunakan pengendali seperti expr1 AND expr2
tidak betul kerana ketidakcocokan parameter. Beberapa pendekatan dibentangkan, masing -masing menangani senario yang berbeza.
kaedah 1: gabungan mudah (parameter yang sama)
Jika kedua -dua ungkapan menggunakan parameter yang sama, pendekatan mudah adalah menggunakan Expression.AndAlso
atau Expression.OrElse
secara langsung pada badan ekspresi:
<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body); var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
penolakan juga mudah:
<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>
Kaedah 2: Menggabungkan ungkapan dengan parameter yang berbeza menggunakan Invoke
Apabila ungkapan mempunyai parameter yang berbeza, kaedah Invoke
boleh digunakan untuk membuat ungkapan lambda baru dengan parameter biasa:
<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
akan sama, menggantikan AndAlso
dengan OrElse
.
Kaedah 3: Gabungan yang dioptimumkan (mengendalikan parameter yang sama dan berbeza)
Kaedah ini secara bijak memilih pendekatan yang lebih mudah jika parameter adalah sama, jika tidak menggunakan 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>
Kaedah 4: Pendekatan EF-selamat menggunakan ExpressionVisitor (.NET 4.0 dan kemudian)
untuk keserasian rangka kerja entiti, ExpressionVisitor
memberikan penyelesaian yang mantap:
<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>
Kaedah ini menggantikan rujukan parameter dalam ungkapan untuk memastikan keserasian dengan pelbagai penyedia LINQ. Pilihan kaedah bergantung kepada keperluan khusus dan konteks aplikasi anda, terutamanya penyedia Linq yang digunakan dan sama ada konsistensi parameter dijamin. Pendekatan ExpressionVisitor
menawarkan penyelesaian yang paling mantap untuk senario kompleks dan integrasi kerangka entiti.
Atas ialah kandungan terperinci Bagaimanakah saya boleh menggabungkan dua ekspresi ekspresi menggunakan dan, atau, dan bukan pengendali di C#?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!