Combine Lambda Expressions

Estoy buscando una forma de combinar dos expresiones lambda, sin usar unaExpression.Invoke en cualquier expresión. Quiero construir esencialmente una nueva expresión que encadene dos separadas. Considere el siguiente 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; }
}

Y digamos que tenía dos expresiones:

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

Y quiero unirlos para obtener funcionalmente la siguiente expresión:

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

La única forma en que podría pensar en hacer esto es usar un ExpressionVisitor como este:

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

Y luego se usa así:

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

Funciona, pero me parece un poco torpe. Todavía estoy tratando de comprender las expresiones de mi cabeza y me pregunto si hay una forma más idiomática de expresar esto, y tengo la astuta sospecha de que me falta algo obvi

Losrazó Quiero hacer esto es usarlo con los ayudantes ASP.net mvc 3 Html. Tengo algunos ViewModels profundamente anidados y algunas extensiones HtmlHelper que ayudan a lidiar con ellos, por lo que la expresión debe ser solo una colección deMemberExpressions para que los ayudantes MVC integrados los procesen correctamente y creen los valores de atributo de nombre correctamente anidados. Mi primer instinto fue usarExpression.Invoke() e invocar la primera expresión y encadenarla a la segunda, pero a los ayudantes de MVC no les gustó mucho. Perdió su contexto jerárquico.

Respuestas a la pregunta(6)

Su respuesta a la pregunta