Convert IEnumerable to DataTable

By Peter Bromberg

One of the problems with converting an IEnumerable to DataTable is the slowness of the reflection required. Here is a better way.

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);

    // 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);


     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(
           BindingFlags.Static | BindingFlags.NonPublic);

        // reflection call to the generic get-method generator to generate the type arguments
       MethodInfo constructedHelper = genericHelper.MakeGenericMethod(

        // 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;

Convert IEnumerable to DataTable  (3006 Views)