Проблема модификации дерева выражений - PullRequest
0 голосов
/ 15 июня 2009

У меня есть следующее:

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

Я хочу удалить параметр и сделать первый член параметром для подвыражения, поэтому я получаю:

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

Это должно работать для любого дерева выражений вышеуказанного формата, включая MemberExpression, MethodCallExpression и любое другое Expression, которое имеет свойство .Expression. Например:

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

или

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

Как бы я достиг этого элегантно?

Спасибо

Andrew

Ответы [ 2 ]

1 голос
/ 15 июня 2009

Начните с класса от этой страницы Затем добавьте этот код, и я думаю, что у вас есть решение (тестовый материал был таким, каким я его тестировал, я думаю, что он почти такой же, как и вы):

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);
    }
}
1 голос
/ 15 июня 2009

Вы проверяли Metalinq и его EditableExpression?

...