Я думаю, что все решения можно улучшить и сделать метод более общим, если вы используете некоторые соглашения и рефлексию. Допустим, вы называете свои столбцы в таблице данных тем же именем, что и свойства в вашем объекте, тогда вы можете написать что-то, что будет проверять все ваши свойства вашего объекта, а затем искать этот столбец в таблице данных для сопоставления значения.
Я сделал обратное, то есть ... из IList в datatable, и код, который я написал, можно увидеть по адресу: http://blog.tomasjansson.com/convert-datatable-to-generic-list-extension/
Не должно быть так сложно идти другим путем, и должно быть так сложно перегружать функции, чтобы вы могли предоставить информацию о том, какие свойства вы хотите включить или исключить.
EDIT:
Итак, код, чтобы заставить его работать:
public static class DataTableExtensions
{
private static Dictionary<Type,IList<PropertyInfo>> typeDictionary = new Dictionary<Type, IList<PropertyInfo>>();
public static IList<PropertyInfo> GetPropertiesForType<T>()
{
var type = typeof(T);
if(!typeDictionary.ContainsKey(typeof(T)))
{
typeDictionary.Add(type, type.GetProperties().ToList());
}
return typeDictionary[type];
}
public static IList<T> ToList<T>(this DataTable table) where T : new()
{
IList<PropertyInfo> properties = GetPropertiesForType<T>();
IList<T> result = new List<T>();
foreach (var row in table.Rows)
{
var item = CreateItemFromRow<T>((DataRow)row, properties);
result.Add(item);
}
return result;
}
private static T CreateItemFromRow<T>(DataRow row, IList<PropertyInfo> properties) where T : new()
{
T item = new T();
foreach (var property in properties)
{
property.SetValue(item, row[property.Name], null);
}
return item;
}
}
Если у вас есть DataTable, вы можете просто написать yourTable.ToList<YourType>()
, и он создаст список для вас. Если у вас более сложный тип с вложенными объектами, вам нужно обновить код. Одно из предложений - просто перегрузить метод ToList
, чтобы принять params string[] excludeProperties
, который содержит все ваши свойства, которые не должны отображаться. Конечно, вы можете добавить проверку нуля в цикл foreach
метода CreateItemForRow
.
ОБНОВЛЕНИЕ: Добавлен статический словарь для сохранения результата от операции отражения, чтобы сделать его немного быстрее. Я не скомпилировал код, но он должен работать :).