2009-04-09 39 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>需要的類型有一個參數的構造函數。