首頁 > 後端開發 > C++ > 我如何使用C#中的操作員和或者不是運算符組合兩個表達式表達式?

我如何使用C#中的操作員和或者不是運算符組合兩個表達式表達式?

DDD
發布: 2025-01-31 05:56:10
原創
941 人瀏覽過

>本文演示瞭如何使用邏輯和OR,而不是運算符組合兩個類型的C#表達式。 由於參數不匹配,直接使用Expression<Func<bool>>之類的操作員是不正確的。 提出了幾種方法,每個方法都解決了不同的方案。 expr1 AND expr2>

方法1:簡單組合(相同的參數)>

兩種表達式都使用相同的參數,則直接在表達式上使用

>或Expression.AndAlso Expression.OrElse

否定同樣簡單:
<code class="language-csharp">var body = Expression.AndAlso(expr1.Body, expr2.Body);
var lambda = Expression.Lambda<Func<bool>>(body, expr1.Parameters[0]);</code>
登入後複製
>

<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>
登入後複製
方法2:使用Indoke 將表達式與不同的參數組合 當表達式具有不同的參數時,可以使用的方法來創建具有共同參數的新lambda表達式:

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>
登入後複製
將是相似的,用

>。 OrElseAndAlso方法3:優化組合(處理相同的和不同的參數)OrElse

>

如果參數相同,此方法智能選擇了更簡單的方法,否則使用>:>

Invoke方法4:使用ExpressionVisitor(.NET 4.0和更高版本)

<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>
登入後複製
的EF-SAFE方法

對於實體框架兼容性,提供了一個可靠的解決方案:>

此方法替換了表達式中的參數參考,以確保與各種LINQ提供商的兼容性。 方法的選擇取決於應用程序的特定需求和上下文,尤其是使用的LINQ提供商以及是否保證了參數一致性。 該方法為複雜的方案和實體框架集成提供了最強大的解決方案。

ExpressionVisitor

<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>
登入後複製

以上是我如何使用C#中的操作員和或者不是運算符組合兩個表達式表達式?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板