从lambda表达式获取propertyinfo,但是使用int失败

时间:2016-11-08 20:22:23

标签: c# reflection lambda expression-trees

获取lambda表达式中项目的所有PropertyInfo的最佳方法是什么。

我想在sql数据库的xml字段上设置过滤器。

var FilterBase = new FilterBase<SimpleItemSubObject>()
                    .SetSimpleFilter(x => x.ID, 123)
                    .SetSimpleFilter(x => x.Test.Name, "demo3");
在de analyzer中,我能够获取Name属性的propertyinfo。

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

如果它是一个字符串属性,它将返回propertyinfo。但是在int的情况下,分析器失败,因为lambda添加了转换函数。

{x => Convert(x.ID)}

它添加了转换功能。

那么在这种情况下为x.ID获取propertyinfo的最佳方法是什么?以及如何阻止使用转换功能

1 个答案:

答案 0 :(得分:2)

编译器添加Convert表达式的事实表明您正在使用具有object返回类型的非泛型lambda表达式。像这样:

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

解决此问题的一种方法是使方法通用(类似于LINQ OrderBy):

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

所以不再有Convert

另一种方法是保持方法不变,并剥离第一个Convert,如果有的话:

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