首頁 >後端開發 >C++ >如何結合LINQ中類型的邏輯表達式?

如何結合LINQ中類型的邏輯表達式?

DDD
DDD原創
2025-01-31 06:01:09563瀏覽

How to Combine Logical Expressions of Type `Expression` in LINQ?

在LINQ中組合Expression<Func<bool>>類型的邏輯表達式

LINQ經常使用表達式,表達式是lambda表達式的表示形式。在處理表達式時,經常需要組合兩個邏輯表達式,例如AND、OR或NOT。

例如,考慮以下兩個表達式:

<code class="language-csharp">Expression<Func<bool>> expr1;
Expression<Func<bool>> expr2;</code>

我們可能希望組合這些表達式以獲得相同類型的新的表達式:

<code class="language-csharp">// 示例用法(原样无效)
Expression<Func<bool>> andExpression = expr1 AND expr2;</code>

組合具有相同參數的表達式

如果expr1expr2都使用相同的參數,則操作很簡單:

<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>

組合具有不同參數的表達式

但是,如果表達式使用不同的參數,我們必須注意如何組合它們。使用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>

通用方法

以下代碼片段提供了一種通用方法,用於確定組合表達式的最合適方法:

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

其他注意事項

在.NET 4.0及更高版本中,可以使用ExpressionVisitor類創建EF安全的表達式:

<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);
}</code>

This revised output maintains the original image and provides a more concise and readable explanation of the code snippets. The code examples are also formatted for better readability.

以上是如何結合LINQ中類型的邏輯表達式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn