问题
I am looking to use CsvHelper dynamically by building up Expressions in code which represent property member access for a given type.
The method I am trying to pass these expressions to has the following signature:
public virtual CsvPropertyMap<TClass, TProperty> Map<TProperty>( Expression<Func<TClass, TProperty>> expression )
{
//
}
So you would normally call it, for any given type you want to map, like this (for a type with a property called 'stringProperty'):
mapper.Map(x => x.StringProperty);
Passing in a lambda which is converted internally into an Expression<Func<T, object>>
I have tried to create this expression in code, using Expressions. At compile time it all works fine (in that it returns an Expression<Func<TModel, object>>
), but at runtime I get an exception 'not a member access'. Here is the code which takes a PropertyInfo object representing the property I want to map:
private Expression<Func<TModel, object>> CreateGetterExpression( PropertyInfo propertyInfo )
{
var getter = propertyInfo.GetGetMethod();
Expression<Func<TModel, object>> expression = m => getter.Invoke( m, new object[] { } );
return expression;
}
Basically, how do I build that Expression up properly in code?
回答1:
Just try something looks like this:
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);
}
It's example of usages:
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 }));
}
来源:https://stackoverflow.com/questions/45067471/create-expressionfunct-object-from-a-given-type