Construct LambdaExpression для вложенного свойства из строки

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

var expression = CreateExpression<Foo, object>(foo => foo.myBar.name);

private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression)
{
    return (expression as Expression);
}

С классами:

class Foo
{
    public Bar myBar { get; set; }
}
class Bar
{
    public string name { get; set; }
}

Однако все, что мне задано, это тип Foo и строка "myBar.name"

Если это было нормальное свойство, например, просто нужно значение "myBar", то я мог бы использовать следующее:

private static LambdaExpression GetPropertyAccessLambda(Type type, string propertyName)
{
    ParameterExpression odataItParameter = Expression.Parameter(type, "$it");
    MemberExpression propertyAccess = Expression.Property(odataItParameter, propertyName);
    return Expression.Lambda(propertyAccess, odataItParameter);
}

Однако этот код не работает для вложенных свойств, и я не уверен, как создать LambdaExpression для работы foo.myBar.name.

Я думаю, что это будет примерно так:

GetExpression(Expression.Call(GetExpression(Foo, "myBar"), "name"))

Но я не могу понять, как заставить все это работать, или если есть лучший способ сделать это во время выполнения.

Ответ 1

Вы имеете в виду:

static LambdaExpression CreateExpression(Type type, string propertyName) {
    var param = Expression.Parameter(type, "x");
    Expression body = param;
    foreach (var member in propertyName.Split('.')) {
        body = Expression.PropertyOrField(body, member);
    }
    return Expression.Lambda(body, param);
}

Например:

class Foo {
    public Bar myBar { get; set; }
}
class Bar {
    public string name { get; set; }
}
static void Main() {
    var expression = CreateExpression(typeof(Foo), "myBar.name");
    // x => x.myBar.name
}

?