Есть две большие проблемы:
- Нельзя указать ограничение конструктора, которое принимает параметр
- Ваш метод в настоящее время не является универсальным - он должен быть
PopulateCollection<T>
вместо PopulateCollection
.
У вас уже есть ограничение T : BusinessBase
, поэтому, чтобы обойти первую проблему, я предлагаю вам добавить абстрактный (или виртуальный) метод в BusinessBase
:
public abstract void PopulateFrom(DataRow dr);
Также добавьте ограничение конструктора без параметров к T
.
Ваш метод может стать:
protected List<T> PopulateCollection(DataTable dt)
where T: BusinessBase, new()
{
List<T> lst = new List<T>();
foreach (DataRow dr in dt.Rows)
{
T t = new T();
t.PopulateFrom(dr);
lst.Add(t);
}
return lst;
}
Если вы используете .NET 3.5, вы можете сделать это немного проще, используя метод расширения в DataTableExtensions
:
protected List<T> PopulateCollection<T>(DataTable dt)
where T: BusinessBase, new()
{
return dt.AsEnumerable().Select(dr =>
{
T t = new T();
t.PopulateFrom(dr);
}.ToList();
}
В качестве альтернативы, вы можете сделать его методом расширения (опять же, при условии .NET 3.5) и передать функцию для возврата экземпляров:
static List<T> ToList<T>(this DataTable dt, Func<DataRow dr, T> selector)
where T: BusinessBase
{
return dt.AsEnumerable().Select(selector).ToList();
}
Ваши абоненты будут писать:
table.ToList(row => new Whatever(row));
Предполагается, что вы вернетесь к получению конструктором DataRow
. Это дает вам преимущество, заключающееся в том, что вы можете писать неизменяемые классы (и те, у которых нет конструктора без параметров), но означает, что вы не можете работать в общем случае, не имея также функции «factory».