Construct LambdaExpression for nested property from string

17,412

Do you mean:

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

For example:

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
}

?

Share:
17,412

Related videos on Youtube

Seph
Author by

Seph

Updated on June 06, 2022

Comments

  • Seph
    Seph almost 2 years

    I am trying to create a lambda expression for a nested property at run-time from the name of the propert. Basically I am trying to create the lambda expression specified by:

    var expression = CreateExpression<Foo, object>(foo => foo.myBar.name);
    
    private static Expression CreateExpression<TEntity, TReturn>(Expression<Func<TEntity, TReturn>> expression)
    {
        return (expression as Expression);
    }
    

    With the classes:

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

    However all I am given is the type of Foo and the string "myBar.name"

    If it were a normal property such as just needing the value "myBar" then I could use the following:

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

    However this code does not work for nested properties and I'm not sure how to create the LambdaExpression to do the work of foo.myBar.name.

    I think it's going to be something like this:

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

    But I can't seem to work out how to get it all working, or if there's a better way to do this at run-time.