Dynamically creating an expression which selects an objects property

c# expression-trees lambda

Question

I want to be able to build up an expression dynamically, which is essentially a property selector.

I am trying to use this so I can provide a flexible search UI and then translate the selected search parameters to an Entity Framework query.

I have most of what I need thanks to another library I am using, but am missing the final part which translates my query string parameters to the appropriate expression selector the other library requires.

The library takes an argument of :

Expression<Func<TObject, TPropertyType>>

An example of how this would be coded if baked into an application would be :

Expression<Func<MyObject, int>> expression = x=> x.IntegerProperty;

However, I need to be able to generate this expression dynamically, as the important point is that all I will know is the type of object (MyObject) and the property name as a string value ("IntegerProperty"). The property value will obviously map to an property on the object which could be of any non complex type.

So essentially I think I am wanting to find a way to build up the expression dynamically which specifies the correct object property to return and where the return value is determined by that property type.

psuedo code :

string ObjectPropertyName
Type ObjectType
Type ObjectPropertyType = typeof(ObjectType).GetProperty(ObjectPropertyName).Property

 Expression<Func<[ObjectType], [ObjectPropertyType]>> expression = x=> x.[ObjectPropertyName];

Update :

I have got as far as this

ParameterExpression objectParameter = Expression.Parameter(type, "x");
MemberExpression objectProperty = Expression.Property(objectParameter, "PropertyNameString");
Expression<Func<ObjectType, int>> expression = Expression.Lambda<Func<ObjectType, int>>(objectProperty, objectParameter);

But the problem I have with this is that the return type is not always an int but may be some other type.

1
4
2/11/2016 3:48:57 PM

Popular Answer

Doing what you asked is bit tricky but not impossible. Since the property type is not known until run time so you can not declare the Expression<Func<,>> so it would be done by reflection.

public static class QueryableExtension
{
    public static object Build<Tobject>(this Tobject source, string propertyName)
    {
        var propInfo = typeof(Tobject).GetProperty(propertyName);

        var parameter = Expression.Parameter(typeof(Tobject), "x");

        var property = Expression.Property(parameter, propInfo);

        var delegateType = typeof(Func<,>)
                           .MakeGenericType(typeof(Tobject), propInfo.PropertyType);

        var lambda = GetExpressionLambdaMethod()
                        .MakeGenericMethod(delegateType)
                        .Invoke(null, new object[] { property, new[] { parameter } });

        return lambda;
    }

    public static MethodInfo GetExpressionLambdaMethod()
    {
       return typeof(Expression)
                     .GetMethods()
                     .Where(m => m.Name == "Lambda")
                     .Select(m => new
                     {
                         Method = m,
                         Params = m.GetParameters(),
                         Args = m.GetGenericArguments()
                     })
                     .Where(x => x.Params.Length == 2
                                 && x.Args.Length == 1
                                 )
                     .Select(x => x.Method)
                     .First();
    }
}

Usage -

var expression = testObject.Build("YourPropertyName");

Now this will build the Expression you desired with return type of property. But since we don't know about your library but I suggest you to call your library method via reflection and pass the expression wrapped under object.

3
2/11/2016 4:18:19 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow