2009-04-09 47 views
1

我有以下的扩展方法调用静态函数,并想使之更加通用的,所以我没有实现它在我们的域中的每个类。我如何可以解决C#的限制,对通用型

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; 
} 

有什么办法可以解决这个令人沮丧的限制吗?

编辑:下面的段落是胡说八道,但我是这么的答案的一个有意义的未来的读者:

用户,以及我的其他类,实现了IDataModelIDataModel只需要1个方法,FromDataRow(DataRow row)。把一个地方放入函数原型显然没有帮助。

回答

9

当你只需要一个方法,认为Func键......也许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; 
} 

然后调用table.ToList<User>(User.FromDataRow)

+0

您可以删除在本例中调用ToList的第一个参数。 – JaredPar 2009-04-09 20:54:05

+0

它应该能够从Func中推断出类型T. – Samuel 2009-04-09 20:57:44

3

在你的示例代码,您正在使用一个静态方法来从创建用户DataRow中:

foreach (DataRow row in table.Rows) 
    users.Add(User.FromDataRow(row)); 

但是,你不能用static的方法来实现一个接口。

假设你的界面看起来是这样的:

public interface IDataModel { 
    void FromDataRow(DataRow row); 
} 

那么你User类将有一个实例方法FromDataRow(),而不是静态的。

如果你的类有参数构造函数,那么你可以这样写:

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; 
} 

<T>IDataModel约束要求实现IDataModel类型。
new()约束上<T>需要的类型有一个参数的构造函数。