Rumah > pembangunan bahagian belakang > C++ > Bagaimana menggabungkan dua objek ekspresi menggunakan pengendali logik?

Bagaimana menggabungkan dua objek ekspresi menggunakan pengendali logik?

Barbara Streisand
Lepaskan: 2025-01-31 05:41:09
asal
311 orang telah melayarinya

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:

How to Combine Two Expression Objects Using Logical Operators?

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

Kaedah ini menggunakan kaedah

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>
Salin selepas log masuk

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>
Salin selepas log masuk

Kaedah 3: ExpressionVisitor

Kaedah canggih ini menggunakan

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>
Salin selepas log masuk
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!

sumber:php.cn
Kenyataan Laman Web ini
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
Artikel terbaru oleh pengarang
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan