Reputation: 37436
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
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