Reading Properties of an Object with Expression Trees
Assuming that you're happy with a Func<TType, object>
delegate (as per the comments above), you can use Expression.Convert
to achieve that:
var properties = typeof(TType).GetProperties().Where(p => p.CanRead);
foreach (var propertyInfo in properties)
{
MethodInfo getterMethodInfo = propertyInfo.GetGetMethod();
ParameterExpression entity = Expression.Parameter(typeof(TType));
MethodCallExpression getterCall = Expression.Call(entity, getterMethodInfo);
UnaryExpression castToObject = Expression.Convert(getterCall, typeof(object));
LambdaExpression lambda = Expression.Lambda(castToObject, entity);
var functionThatGetsValue = (Func<TType, object>)lambda.Compile();
}
After hours of googling found the answer here. I've added the snippets from the blog post as it might help others having the same troubles:
public static class PropertyInfoExtensions
{
public static Func<T, object> GetValueGetter<T>(this PropertyInfo propertyInfo)
{
if (typeof(T) != propertyInfo.DeclaringType)
{
throw new ArgumentException();
}
var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
var property = Expression.Property(instance, propertyInfo);
var convert = Expression.TypeAs(property, typeof(object));
return (Func<T, object>)Expression.Lambda(convert, instance).Compile();
}
public static Action<T, object> GetValueSetter<T>(this PropertyInfo propertyInfo)
{
if (typeof(T) != propertyInfo.DeclaringType)
{
throw new ArgumentException();
}
var instance = Expression.Parameter(propertyInfo.DeclaringType, "i");
var argument = Expression.Parameter(typeof(object), "a");
var setterCall = Expression.Call(
instance,
propertyInfo.GetSetMethod(),
Expression.Convert(argument, propertyInfo.PropertyType));
return (Action<T, object>)Expression.Lambda(setterCall, instance, argument).Compile();
}
}