Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Changing parameter name in a LambdaExpression just for display

Tags:

c#

lambda

Let's say I have an expression like this:

Expression<Predicate<T>> exp

If I assign the following expression:

a => a.First() != 0

and then I call exp.ToString() I will obtain exactly the expression I passed, that is perfectly good, but, suppose we want to change the name we use for 'a' with something else, how can we do ? String replacement would not do in all the case ( it works in the example above,but what if the parameter was called 'i' for example ?) Is it possible to have just the parameter name replacement, run time, without affecting the expression semantic ?

UPDATE The @PhilKlein works perfectly, but requires framework 4. But if we need to target the framework 3.5 we can use an ExpressionVisitor class from Matt Warren, by just modifing from protected to public the Visit method.

like image 578
Felice Pollano Avatar asked Dec 16 '11 22:12

Felice Pollano


1 Answers

It's quick and dirty, but assuming you're using .NET 4.0 you could create the following:

public class PredicateRewriter
{
    public static Expression<Predicate<T>> Rewrite<T>(Expression<Predicate<T>> exp, string newParamName)
    {
        var param = Expression.Parameter(exp.Parameters[0].Type, newParamName);
        var newExpression = new PredicateRewriterVisitor(param).Visit(exp);

        return (Expression<Predicate<T>>) newExpression;
    }

    private class PredicateRewriterVisitor : ExpressionVisitor
    {
        private readonly ParameterExpression _parameterExpression;

        public PredicateRewriterVisitor(ParameterExpression parameterExpression)
        {
            _parameterExpression = parameterExpression;
        }

        protected override Expression VisitParameter(ParameterExpression node)
        {
            return _parameterExpression;
        }
    }
}

And then use it as follows:

var newExp = PredicateRewriter.Rewrite(exp, "b");
newExp.ToString(); // returns "b => (b.First() == 0)" in your case
like image 153
Phil Klein Avatar answered Oct 16 '22 19:10

Phil Klein