Это не будет реальной утечкой , но это может привести к ненужным стрессам ...
Сколько строк вы работаете над?
Обратите внимание, что отражение - это боль, и что каждый вызов таких вещей, как GetCustomAttributes
, может возвращать новый массив (так что вы хотите сделать это один раз, а не один раз для каждого свойства в строке).
Лично я заранее построю работу, которую собираюсь сделать ... что-то вроде ниже.
Обратите внимание, что если бы я делал это много, я бы либо переключился на HyperDescriptor , либо, если бы был вариант .NET 3.5, может быть, скомпилированное выражение. Поскольку DataTable
не является строго типизированным, HyperDescriptor
будет следующим логическим шагом (для повышения производительности) после приведенного ниже ...
sealed class Tuple<T1, T2>
{
public Tuple() {}
public Tuple(T1 value1, T2 value2) {Value1 = value1; Value2 = value2;}
public T1 Value1 {get;set;}
public T2 Value2 {get;set;}
}
public static List<T> Convert<T>(DataTable table)
where T : class, new()
{
List<Tuple<DataColumn, PropertyInfo>> map =
new List<Tuple<DataColumn,PropertyInfo>>();
foreach(PropertyInfo pi in typeof(T).GetProperties())
{
ColumnAttribute col = (ColumnAttribute)
Attribute.GetCustomAttribute(pi, typeof(ColumnAttribute));
if(col == null) continue;
if(table.Columns.Contains(col.FieldName))
{
map.Add(new Tuple<DataColumn,PropertyInfo>(
table.Columns[col.FieldName], pi));
}
}
List<T> list = new List<T>(table.Rows.Count);
foreach(DataRow row in table.Rows)
{
if(row == null)
{
list.Add(null);
continue;
}
T item = new T();
foreach(Tuple<DataColumn,PropertyInfo> pair in map) {
object value = row[pair.Value1];
if(value is DBNull) value = null;
pair.Value2.SetValue(item, value, null);
}
list.Add(item);
}
return list;
}