Combine Lambda Expressions

Estou procurando uma maneira de combinar duas expressões lambda, sem usar umExpression.Invoke em qualquer expressão. Quero essencialmente criar uma nova expressão que encadeie duas expressões separadas. Considere o seguinte código:

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

E vamos dizer que eu tinha duas expressões:

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

E eu quero juntá-los para obter funcionalmente a seguinte expressão:

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

A única maneira de pensar em fazer isso é usar um ExpressionVisitor assim:

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

E então é usado assim:

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

Funciona, mas me parece um pouco desajeitado. Ainda estou tentando entender a expressão da minha cabeça e me perguntando se existe uma maneira mais idiomática de expressar isso, e tenho a suspeita furtiva de que estou perdendo algo óbvi

Orazã Eu quero fazer isso é usá-lo com os auxiliares do ASP.net mvc 3 Html. Eu tenho algumas ViewModels profundamente aninhadas e algumas extensões HtmlHelper que ajudam a lidar com elas, então a expressão precisa ser apenas uma coleção deMemberExpressions para os auxiliares integrados do MVC processá-los corretamente e criar os valores de atributo de nome profundamente aninhados corretamente. Meu primeiro instinto foi usarExpression.Invoke() e invoque a primeira expressão e encadeie-a na segunda, mas os ajudantes do MVC não gostaram muito disso. Perdeu seu contexto hierárquico.

questionAnswers(6)

yourAnswerToTheQuestion