部分应用表达式树

Ric*_*lly 3 c# expression-trees c#-5.0

我有一个表达式,形式如下:

Expression<Func<T, bool>> predicate = t => t.Value == "SomeValue";
Run Code Online (Sandbox Code Playgroud)

是否可以创建此表达式的"部分应用"版本:

Expression<Func<bool>> predicate = () => t.Value == "SomeValue";
Run Code Online (Sandbox Code Playgroud)

NB此表达式实际上从未被编译或调用,仅检查它以生成一些SQL.

Dar*_*rov 5

这可以通过编写自定义ExpressionVisitor并使用在闭包中捕获的常量表达式替换参数来轻松实现:

public class Foo
{
    public string Value { get; set; }
}

public class ReplaceVisitor<T> : ExpressionVisitor
{
    private readonly T _instance;
    public ReplaceVisitor(T instance)
    {
        _instance = instance;
    }

    protected override Expression VisitParameter(ParameterExpression node)
    {
        return Expression.Constant(_instance);
    }
}

class Program
{
    static void Main()
    {
        Expression<Func<Foo, bool>> predicate = t => t.Value == "SomeValue";
        var foo = new Foo { Value = "SomeValue" };
        Expression<Func<bool>> result = Convert(predicate, foo);

        Console.WriteLine(result.Compile()());
    }

    static Expression<Func<bool>> Convert<T>(Expression<Func<T, bool>> expression, T instance)
    {
        return Expression.Lambda<Func<bool>>(
            new ReplaceVisitor<T>(instance).Visit(expression.Body)
        );
    }
}
Run Code Online (Sandbox Code Playgroud)