Get propertyinfo from lambda expression, but fails with int

c# expression-trees lambda reflection

Question

What is the best way to get to all the PropertyInfo of items in a lambda expression.

i want to set a filter on a xml field in a sql database.

var FilterBase = new FilterBase<SimpleItemSubObject>()
                    .SetSimpleFilter(x => x.ID, 123)
                    .SetSimpleFilter(x => x.Test.Name, "demo3");

in de analyser, i'm able to get the propertyinfo for the Name property.

internal IEnumerable<PropertyInfo> GetExpressionList()
{
    return GetPropertyListfor(lambda.Body as MemberExpression);
}

private IEnumerable<PropertyInfo> GetPropertyListfor(MemberExpression body)
{
    var result = new List<PropertyInfo>();
    if (body != null && body.Expression != null)
    {
        result.AddRange(GetPropertyListfor(body.Expression as MemberExpression));
        result.Add((body as MemberExpression).Member as PropertyInfo);
    }

    return result;
}

this will return the propertyinfo if it's a string property. but in case of a int the analyser fails because lambda has added a convert function.

{x => Convert(x.ID)}

It added a convert function.

so what is the best method of getting the propertyinfo in this case for the x.ID. and how do i prevent the use of the convert function

Accepted Answer

The fact that compiler adds Convert expression indicates that you are using non generic lambda expression with object return type. Something like this:

public class FilterBase<T>
{
    public FilterBase<T> SetSimpleFilter(Expression<Func<T, object>> selector, object value)
    {
        // ...
        return this;
    }
}

One way to resolve the issue is to make the method generic (similar to LINQ OrderBy):

public FilterBase<T> SetSimpleFilter<V>(Expression<Func<T, V>> selector, V value)

so there will not be Convert anymore.

Another way is to keep the method as is, and strip the first Convert if any:

internal IEnumerable<PropertyInfo> GetExpressionList()
{
    var body = lambda.Body;
    if (body.NodeType == ExpressionType.Convert)
        body = ((UnaryExpression)body).Operand;
    return GetPropertyListfor(body as MemberExpression);
}


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why