LEATH
首先,您需要添加一个where T:class约束-你不能打电话GetValue关于值类型,除非它们是经过的ref.第二GetValue很慢而且经常被打电话。为了解决这个问题,我们可以创建一个委托,然后调用它:MethodInfo method = property.GetGetMethod(true);Delegate.CreateDelegate(typeof(Func<TClass, TProperty>), method );问题是我们不知道TProperty,但像往常一样乔恩·斯基特有答案-我们可以使用反射检索getter委托,但是一旦有了它,我们就不需要再进行反射:public class ReflectionUtility{
internal static Func<object, object> GetGetter(PropertyInfo property)
{
// get the get method for the property
MethodInfo method = property.GetGetMethod(true);
// get the generic get-method generator (ReflectionUtility.GetSetterHelper<TTarget, TValue>)
MethodInfo genericHelper = typeof(ReflectionUtility).GetMethod(
"GetGetterHelper",
BindingFlags.Static | BindingFlags.NonPublic);
// reflection call to the generic get-method generator to generate the type arguments
MethodInfo constructedHelper = genericHelper.MakeGenericMethod(
method.DeclaringType,
method.ReturnType);
// now call it. The null argument is because it's a static method.
object ret = constructedHelper.Invoke(null, new object[] { method });
// cast the result to the action delegate and return it
return (Func<object, object>) ret;
}
static Func<object, object> GetGetterHelper<TTarget, TResult>(MethodInfo method)
where TTarget : class // target must be a class as property sets on structs need a ref param
{
// Convert the slow MethodInfo into a fast, strongly typed, open delegate
Func<TTarget, TResult> func = (Func<TTarget, TResult>) Delegate.CreateDelegate(typeof(Func<TTarget, TResult>), method);
// Now create a more weakly typed delegate which will call the strongly typed one
Func<object, object> ret = (object target) => (TResult) func((TTarget) target);
return ret;
}}现在,您的方法变成:public static DataTable ToDataTable<T>(this IEnumerable<T> items)
where T: class{
// ... create table the same way
var propGetters = new List<Func<T, object>>();foreach (var prop in props)
{
Func<T, object> func = (Func<T, object>) ReflectionUtility.GetGetter(prop);
propGetters.Add(func);
}
// Add the property values per T as rows to the datatable
foreach (var item in items)
{
var values = new object[props.Length];
for (var i = 0; i < props.Length; i++)
{
//values[i] = props[i].GetValue(item, null);
values[i] = propGetters[i](item);
}
table.Rows.Add(values);
}
return table; }您可以通过在静态字典中存储每个类型的getter来进一步优化它,然后对每个类型只进行一次反射开销。