I prefer to return IEnumerable
to List
and reflect in the opposite direction, assigning all properties and fields with matching column names:
Using some extensions on MemberInfo
to handle properties or fields:
public static object GetValue(this MemberInfo member, object srcObject) {
if (member.MemberType == MemberTypes.Property)
return ((PropertyInfo)member).GetValue(srcObject, null);
else if (member.MemberType == MemberTypes.Field)
return ((FieldInfo)member).GetValue(srcObject);
else
throw new Exception("Property must be of type FieldInfo or PropertyInfo");
}
public static void SetValue<T>(this MemberInfo member, object destObject, T value) {
if (member.MemberType == MemberTypes.Property)
((PropertyInfo)member).SetValue(destObject, value);
else if (member.MemberType == MemberTypes.Field)
((FieldInfo)member).SetValue(destObject, value);
else
throw new Exception("Property must be of type FieldInfo or PropertyInfo");
}
public static Type GetMemberType(this MemberInfo member) {
switch (member.MemberType) {
case MemberTypes.Field:
return ((FieldInfo)member).FieldType;
case MemberTypes.Property:
return ((PropertyInfo)member).PropertyType;
case MemberTypes.Event:
return ((EventInfo)member).EventHandlerType;
default:
throw new ArgumentException("MemberInfo must be if type FieldInfo, PropertyInfo or EventInfo", "member");
}
}
You can get the list of members with columns and assign them:
public static IEnumerable<T> ToEnumerable<T>(this DataTable dt) where T : new() {
var props = typeof(T).GetMembers(BindingFlags.Public|BindingFlags.Instance)
.Where(p => dt.Columns.Contains(p.Name) && (p.MemberType == MemberTypes.Field || p.MemberType == MemberTypes.Property)).ToList();
foreach (var row in dt.AsEnumerable()) {
var aT = new T();
foreach (var p in props)
p.SetValue(aT, row[p.Name]);
yield return aT;
}
}