创建表达式<func <t,object =“”>&gt;来自给定的类型

时间:2017-07-12 21:03:14

标签: c# reflection lambda expression

我希望通过在代码中构建表达式来动态使用CsvHelper,代码表示给定类型的属性成员访问权。

我尝试将这些表达式传递给的方法具有以下签名:

try (BufferedReader br = new BufferedReader(new FileReader(path))) {
        // your code
}
// Resource will be closed automatically at this line

所以你通常会调用它,对于你要映射的任何给定类型,就像这样(对于一个带有'stringProperty'属性的类型):

    public virtual CsvPropertyMap<TClass, TProperty> Map<TProperty>( Expression<Func<TClass, TProperty>> expression )
    {
        //
    }

传入一个内部转换为mapper.Map(x => x.StringProperty);

的lambda

我尝试使用表达式在代码中创建此表达式。在编译时它一切正常(因为它返回Expression<Func<T, object>>),但在运行时我得到一个异常'不是成员访问'。以下是代表我想要映射的属性的PropertyInfo对象的代码:

Expression<Func<TModel, object>>

基本上,我如何在代码中正确构建表达式?

1 个答案:

答案 0 :(得分:4)

尝试看起来像这样的东西:

    public static Expression<Func<T, P>> GetGetter<T, P>(string propName)
    {
        var parameter = Expression.Parameter(typeof(T));
        var property = Expression.Property(parameter, propName);
        return Expression.Lambda<Func<T, P>>(property, parameter);
    }

    public static Expression<Func<T, P>> GetGetter<T, P>(PropertyInfo propInfo)
    {
        var parameter = Expression.Parameter(typeof(T));
        var property = Expression.Property(parameter, propInfo);
        return Expression.Lambda<Func<T, P>>(property, parameter);
    }

这是用法的例子:

    private class TestCalss
    {
        public int Id { get; set; }
    }

    private static void Main(string[] args)
    {
        var getter = GetGetter<TestCalss, int>(typeof(TestCalss).GetProperty("Id")).Compile();
        Console.WriteLine(getter(new TestCalss { Id = 16 }));
    }