簡體   English   中英

C#-使用lambda將表達式參數轉換為另一個表達式?

[英]C# - Expression parameter into another Expression using lambda?

作為WPF應用程序的一部分,我正在構建一個表達式樹並生成一個謂詞以用作過濾器。 代碼看起來像這樣:

public Expression BuildExpression(Expression parameter, string value)
{
    MethodInfo toStringMethod = new Func<Object, string>((a) => a.ToString()).Method;
    Expression lhs = Expression.Call(parameter, toStringMethod );
    ConstantExpression rhs = Expression.Constant(value);
    BinaryExpression result = Expression.Equal(lhs, rhs);
    return result;
}

這是因為參數是未知類型的表達式-它可能是int,字符串,Guid或其他任何值。 問題在於,如果沒有大量評論,很難理解這里發生的事情。 我真的很想在這里使用lambda:

return parameter => parameter.ToString() == value;

問題在於這不能按預期方式工作-生成的委托將在Expression上調用ToString()而不是表達式的 如果有幫助,則參數為MemberExpression。

我能夠找到一種方法,只需很少的額外代碼。 該解決方案的主要靈感來自Mark Gravell對組合兩個表達式(Expression <Func <T,bool >>)的回答。

從.net 4.0開始。 有ExpressionVistor類,它允許您構建EF安全的表達式。

Expression<TDelegate>是從LambdaExpression派生的(如果您有興趣了解有關它們實際工作方式的更多信息,建議您查看“ LINQ-Expression Tree Visualizer”示例,該示例當前位於https://code.msdn.microsoft .com / LINQ-Expression-Tree-47608cb5 )。 這行代碼:

Expression<Predicate<Object>> e1 = a => a.ToString() == "foo";

使用單個ParameterExpression(Type:Object,ReturnType:Boolean,Body:(LogicalBinaryExpression))創建一個LambdaExpression。 使用自定義ExpressionVisitor,我們可以修改Lambda的主體以創建與之前的代碼相同的結果:

public 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);
    }
}

// Elsewhere...
public Expression BuildExpression(Expression parameter, string value)
{
    Expression<Predicate<Object>> e1 = a => a.ToString() == value;
    return (new ReplaceExpressionVisitor(e1.Parameters[0], parameter)).Visit(e1.Body);
}

肯定可以進行進一步的清理(提供靜態和/或擴展方法),但這可以滿足我的需求。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM