表达式树修改问题

时间:2009-06-15 18:20:44

标签: c# expression-trees

我有以下内容:

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

我想删除参数,并使第一个成员成为子表达式的参数,所以我最终得到:

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

这需要适用于上述格式的任何表达式树,包括MemberExpressionMethodCallExpression以及具有Expression属性的任何其他.Expression。例如:

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

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

我如何优雅地实现这一目标?

由于

安德鲁

2 个答案:

答案 0 :(得分:1)

您是否查看了Metalinq及其EditableExpression?

答案 1 :(得分:1)

this page的课程开始 然后撒上这个代码,我认为你有一个解决方案(测试的东西是我如何测试它,我认为它与你所做的几乎相同):

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