Rumah >pembangunan bahagian belakang >C++ >Bagaimanakah saya boleh menggabungkan dua ekspresi ekspresi menggunakan dan, atau, dan bukan pengendali di C#?

Bagaimanakah saya boleh menggabungkan dua ekspresi ekspresi menggunakan dan, atau, dan bukan pengendali di C#?

DDD
DDDasal
2025-01-31 05:56:10943semak imbas

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.

How Can I Combine Two Expression Expressions Using AND, OR, and NOT Operators in C#?

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!

Kenyataan:
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn