Andrew Bullock
Andrew Bullock

Reputation: 37436

Expression tree modification problem

I have the following:

Expression<Func<Car, int>> myExpr = car => car.Wheel.Tyre.Pressure;

I want to remove the parameter, and make the first member the parameter for a sub-expression, so i end up with:

Expression<Func<Wheel, int>> mySubExpr = wheel => wheel.Tyre.Pressure;

This needs to work for any expression tree of the above format, including MemberExpression, MethodCallExpression and any other Expression which has a .Expression property. For example:

Expression<Func<Car, int>> myOtherExpr = car => car.GetRearLeftWheel().GetTyre().Pressure

or

Expression<Func<Car, int>> anotherExpr = car => car.Wheel.GetTyre().GetPressure();

How would I achieve this elegantly?

Thanks

Andrew

Upvotes: 0

Views: 617

Answers (2)

Jake Pearson
Jake Pearson

Reputation: 27757

Start with the class from this page Then sprinkle in this code and I think you have a solution (the test stuff was how I tested it, I think it is pretty much the same as what you did):

class Test
{
    public Test()
    {
        Expression<Func<string, string>> trim2 = s => s.Substring(1).Substring(1);
        var modifier = new PopModifier();
        Expression<Func<string, string>> trim1 = (Expression<Func<string, string>>)modifier.Modify(trim2);

        var test2 = trim2.Compile();
        var test1 = trim1.Compile();
        var input = "abc";
        if (test2(input) != "c")
        {
            throw new Exception();
        }
        if (test1(input) != "bc")
        {
            throw new Exception();
        }           
    }
}

public class PopModifier : ExpressionVisitor
{
    bool didModify = false;

    public Expression Modify(Expression expression)
    {
        return Visit(expression);
    }

    protected override Expression VisitMethodCall(MethodCallExpression m)
    {
        if (!didModify)
        {
            didModify = true;
            return m.Object;
        }

        return base.VisitMethodCall(m);
    }
}

Upvotes: 1

Andriy Volkov
Andriy Volkov

Reputation: 18933

Did you check out Metalinq and its EditableExpression?

Upvotes: 1

Related Questions