public static DataTable ToDataTable<T>(this IEnumerable<T> items)
where T: class
{
DataTable table = new DataTable(typeof(T).Name);
object[] a_oValues;
int i;
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;
}
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;
}
}