There are two big problems:
- You can't specify a constructor constraint which takes a parameter
- Your method isn't currently generic - it should be
PopulateCollection<T>
instead of PopulateCollection
.
You've already got a constraint that T : BusinessBase
, so to get round the first problem I suggest you add an abstract (or virtual) method in BusinessBase
:
public abstract void PopulateFrom(DataRow dr);
Also add a parameterless constructor constraint to T
.
Your method can then become:
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;
}
If you're using .NET 3.5, you can make this slightly simpler using the extension method in 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();
}
Alternatively, you could make it an extension method itself (again, assuming .NET 3.5) and pass in a function to return instances:
static List<T> ToList<T>(this DataTable dt, Func<DataRow dr, T> selector)
where T: BusinessBase
{
return dt.AsEnumerable().Select(selector).ToList();
}
Your callers would then write:
table.ToList(row => new Whatever(row));
This assumes you go back to having a constructor taking a DataRow
. This has the benefit of allowing you to write immutable classes (and ones which don't have a parameterless constructor) it but does mean you can't work generically without also having the "factory" function.