Параметр привязки в деревьях выражений - PullRequest
10 голосов
/ 23 декабря 2011

Я хотел бы знать, как привязать параметры к значениям в дереве выражений

Что-то вроде

Expression<Func<String, String, bool>> e1 = (x,y) => x == y;

Тогда я бы хотел связать y, сохранив его как одно выражение. Очевидной попыткой было бы что-то вроде

Expresion<Func<String, bool>> e2 = x => e1(x, "Fixed Value Here");

Но это превратило бы мое выражение в узел Invoke. Есть ли способ просто связать параметр в моем первом выражении при получении сигнатуры второго выражения?

1 Ответ

17 голосов
/ 23 декабря 2011
Expression<Func<String, String, bool>> e1 = (x,y) => x == y;

var swap = new ExpressionSubstitute(e1.Parameters[1],
    Expression.Constant("Fixed Value Here"));
var lambda = Expression.Lambda<Func<string, bool>>(
    swap.Visit(e1.Body), e1.Parameters[0]);

с

class ExpressionSubstitute : ExpressionVisitor
{
    public readonly Expression from, to;
    public ExpressionSubstitute(Expression from, Expression to)
    {
        this.from = from;
        this.to = to;
    }
    public override Expression Visit(Expression node)
    {
        if (node == from) return to;
        return base.Visit(node);
    }
}

при этом используется ExpressionVisitor для перестроения выражения с заменой y на константу.

Другой подход заключается в использовании Expression.Invoke, ноэто работает не во всех случаях.

...