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

Bagaimana menggabungkan dua objek ekspresi menggunakan pengendali logik?

Barbara Streisand
Barbara Streisandasal
2025-01-31 05:41:09313semak imbas

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>

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

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>
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!

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