Reputation: 7441
I have the following extension method, and would like to make it more generic so I don't have to implement it for every class in our domain.
public static IList<User> ToList(this DataTable table)
{
IList<User> users = new List<User>();
foreach (DataRow row in table.Rows)
users.Add(User.FromDataRow(row));
return users;
}
Is there any way to work around this frustrating limitation?
edit: the below paragraph is bollocks, but I'm keeping it so one of the answers makes sense to future readers:
User, as well as my other classes, implements IDataModel
. IDataModel
only requires 1 method, FromDataRow(DataRow row)
. Putting a where into the function prototype obviously doesn't help.
Upvotes: 1
Views: 693
Reputation: 44307
In your example code, you're using a static method to create the user from the DataRow:
foreach (DataRow row in table.Rows)
users.Add(User.FromDataRow(row));
But, you can't use static
methods to implement an interface.
Assuming that your interface looks like this:
public interface IDataModel {
void FromDataRow(DataRow row);
}
then your User
class will have an instance method FromDataRow()
, not a static one.
If your classes have parameterless constructors, then you could write this:
public static IList<T> ToList<T>(this DataTable table)
where T : IDataModel, new()
{
IList<T> results = new List<T>();
foreach (DataRow row in table.Rows)
{
T item = new T();
item.FromDataRow(row);
results.Add(item);
}
return users;
}
The IDataModel
constraint on <T>
requires the type to implement IDataModel.
The new()
constraint on <T>
requires the type to have a parameterless constructor.
Upvotes: 3
Reputation: 1062725
When you only need one method, think Func... perhaps a Func<DataRow, T>
public static IList<T> ToList<T>(this DataTable table,
Func<DataRow,T> converter)
{
IList<T> list = new List<T>();
foreach (DataRow row in table.Rows)
list.Add(converter(row));
return list;
}
Then call table.ToList<User>(User.FromDataRow)
Upvotes: 9