我有一些代码片段,如下所示:
想要通过在运行时检查类型来解决此问题。
PropertyInfo pi = type.GetProperty("propertyName");
var expression = new Object(); // this give me error after expression runs!
// Want to resolve this conditation by checking the type at runtime.
if (pi.PropertyType == typeof(DateTime))
{
// Want to pass the generic type parameter which has a same type created at runtime by identifying the property type.
expression = BuildExpression<T, DateTime>(data, group.Member);
}
private Func<T, V> BuildExpression<T, V>(IEnumerable<T> items, string propertyName)
{
Type type = typeof(T);
PropertyInfo pi = type.GetProperty(propertyName);
Type PropertyType = pi.DeclaringType;
var parameter = Expression.Parameter(typeof(T), propertyName);
var cast = Expression.TypeAs(parameter, pi.DeclaringType);
var getterBody = Expression.Property(cast, pi);
var exp = Expression.Lambda<Func<T, V>>(getterBody, parameter);
return exp.Compile();
}
问题: 我必须在类型I上写条件,我必须通过反射检查属性的类型,然后必须构建表达式。
我想要的是什么: 我想检查运行时的属性类型,并希望构建该类型的运行时通用参数,该参数与属性类型相同。
基本上我想删除类型检查上的If
条件 和我想要的是,代码应该automatically detect the property type
并在Generic parameter argument
中传递相同的类型,所以我不必检查具有If
条件的所有类型。与string, decimal, double etc..
您能不能让我知道该决议,因为我想在运行时检查property
类型,并希望使用与属性相同的类型创建Generic parameter type
。
答案 0 :(得分:1)
有一个返回Func<T,V>
(对象T
和成员类型V
)的方法是有问题的,因为在运行时你无法对它做任何有用的事情。如果在编译时不知道T
和V
,则无法将其分配给类型代理,并且使用DynamicInvoke
不是一个好主意。坦率地说,你最好建立一个Func<object,object>
,并在运行时只处理object
。反思和泛型不能很好地混合。
private static Func<object, object> BuildExpression(
Type type, string propertyName)
{
var parameter = Expression.Parameter(typeof(object));
var body = Expression.TypeAs(Expression.PropertyOrField(Expression.TypeAs(
parameter, type), propertyName), typeof(object));
return Expression.Lambda<Func<object, object>>(body, parameter).Compile();
}
但是,此时你可以,IMO,只需切换到FastMember这样的库,并使用基于名称的访问:
var accessor = TypeAccessor.Create(type);
var obj = ...
var propVal = accessor[obj, propertyName];