Search code examples
c#expression-treesc#-5.0

Partial application of an expression tree


I have an Expression in the following form:

Expression<Func<T, bool>> predicate = t => t.Value == "SomeValue";

Is it possible to create a 'partially applied' version of this expression:

Expression<Func<bool>> predicate = () => t.Value == "SomeValue";

NB This expression is never actually compiled or invoked, it is merely inspected to generate some SQL.


Solution

  • This could be easily achieved by writing a custom ExpressionVisitor and replacing the parameter with a constant expression that you have captured in a closure:

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