Объединить лямбда-выражения

Я ищу способ объединить два лямбда-выражения, не используяExpression.Invoke на любом выражении. Я хочу по существу построить новое выражение, которое объединяет два отдельных. Рассмотрим следующий код:

class Model {
    public SubModel SubModel { get; set;}
}

class SubModel {
    public Foo Foo { get; set; }
}

class Foo {
    public Bar Bar { get; set; }
}

class Bar {
    public string Value { get; set; }
}

И скажем, у меня было два выражения:

Expression<Func<Model, Foo>> expression1 = m => m.SubModel.Foo;
Expression<Func<Foo, string>> expression2 = f => f.Bar.Value;

И я хочу соединить их вместе, чтобы функционально получить следующее выражение:

Expression<Func<Model, string>> joinedExpression = m => m.SubModel.Foo.Bar.Value;

Единственный способ сделать это - использовать ExpressionVisitor следующим образом:

public class ExpressionExtender<TModel, TIntermediate> : ExpressionVisitor
{
    private readonly Expression<Func<TModel, TIntermediate>> _baseExpression;

    public ExpressionExtender(Expression<Func<TModel, TIntermediate>> baseExpression)
    {
        _baseExpression = baseExpression;
    }

    protected override Expression VisitMember(MemberExpression node)
    {
        _memberNodes.Push(node.Member.Name);
        return base.VisitMember(node);
    }

    private Stack<string> _memberNodes;

    public Expression<Func<TModel, T>> Extend<T>(Expression<Func<TIntermediate, T>>  extend)
    {
        _memberNodes = new Stack<string>();
        base.Visit(extend);
        var propertyExpression  = _memberNodes.Aggregate(_baseExpression.Body, Expression.Property);
        return Expression.Lambda<Func<TModel, T>>(propertyExpression, _baseExpression.Parameters);
    }
}

А потом его использовали так:

var expExt = new ExpressionExtender<Model, Foo>(expression1);
var joinedExpression = expExt.Extend(expression2);

Это работает, но мне кажется немного неуклюжим. Я все еще пытаюсь обернуть голову выражениями и задаюсь вопросом, есть ли более идиоматический способ выразить это, и у меня есть подлое подозрение, что я упустил что-то очевидное.

причина Я хочу сделать это, чтобы использовать его с помощниками ASP.net MVC 3 Html. У меня есть несколько глубоко вложенных ViewModels и некоторые расширения HtmlHelper, которые помогают справиться с ними, поэтому выражение должно быть просто наборомMemberExpressions для встроенных помощников MVC, чтобы правильно их обрабатывать и строить правильно глубоко вложенные значения атрибута имени. Мой первый инстинкт должен был использоватьExpression.Invoke() и вызвать первое выражение и связать его со вторым, но помощникам MVC это не очень понравилось. Он потерял свой иерархический контекст.

Ответы на вопрос(3)

Ваш ответ на вопрос