DynamicObject & ExpandoObject should be accessed in different way.
public static DataTable ToDataTable<T>( IEnumerable<T> input, string tableName) { var dt = new DataTable(); dt.TableName = tableName; if (input == null || !input.Any()) return dt; if (typeof (T) == typeof(System. Object)) { //"T is dynamic type" var first = Enumerable .First(input); if (first is IDictionary< string, object >) //ExpandoObject also falls into this category { IDictionary<string , object> properties = ( IDictionary<string , object>)first; foreach (var p in properties) { var type = p.Value.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) type = type.GetGenericArguments()[0]; dt.Columns.Add(p.Key, type); } foreach (T r in input) { var values = new object[properties.Count]; int i = 0; foreach (var p in properties) { values[i] = (r as IDictionary <string, object>)[p.Key]; i++; } dt.LoadDataRow(values, true); } } else if (first is System.Dynamic. DynamicObject) { var firstDO = first as System.Dynamic.DynamicObject; var properties = firstDO.GetDynamicMemberNames(); foreach (var p in properties) { var pObject = GetDynamicMember(first, p); var type = pObject.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) type = type.GetGenericArguments()[0]; dt.Columns.Add(p, type); } foreach (T r in input) { var values = new object[properties.Count()]; int i = 0; foreach (var p in properties) { values[i] = GetDynamicMember(r, p); i++; } dt.LoadDataRow(values, true); } } } else { // T is static type var properties = typeof (T).GetProperties(); foreach (var p in properties) { var type = p.PropertyType; if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable <>)) type = type.GetGenericArguments()[0]; dt.Columns.Add(p.Name, type); } foreach (T r in input) { var values = new object[properties.Length]; int i = 0; foreach (var p in properties) { values[i] = p.GetValue(r, null); i++; } dt.LoadDataRow(values, true); } } return dt; } //todo cache the callsite private static object GetDynamicMember( object obj, string memberName) { var binder = Binder .GetMember(CSharpBinderFlags.None, memberName, obj.GetType(), new[] { CSharpArgumentInfo .Create(CSharpArgumentInfoFlags.None, null) }); var callsite = CallSite <Func< CallSite, object , object>>.Create(binder); return callsite.Target(callsite, obj); }