有兩個大問題:
- 不能指定一個構造函數約束,這需要參數
- 你的方法不是當前通用的 - 它應該是
PopulateCollection<T>
而不是PopulateCollection
。
你已經有了一個約束T : BusinessBase
,所以要避開的第一個問題,我建議你在BusinessBase
添加一個抽象的(或者虛擬的)方法:
public abstract void PopulateFrom(DataRow dr);
同時添加參數的構造函數約束到T
。
那麼你的方法能成爲:
protected List<T> PopulateCollection<T>(DataTable dt)
where T: BusinessBase, new()
{
return dt.AsEnumerable().Select(dr =>
{
T t = new T();
t.PopulateFrom(dr);
}.ToList();
}
或者,您可以:
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
擴展方法使使其成爲擴展方法本身(再次假設.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();
}
01然後級
您的呼叫會寫:
table.ToList(row => new Whatever(row));
這是假設你回去有一個構造採取DataRow
。這樣做的好處是可以編寫不可變類(以及沒有無參數構造函數的類),但這意味着如果沒有「工廠」功能,就無法工作。
+1清除問題,併爲最後的版本。在這種情況下,我認爲中間版本並不比foreach簡單。 – eglasius 2009-04-23 09:04:05
我沒有編輯的權力,所以任何人都可以,改變 返回dt.Rows.AsEnumerable()。Select(selector).ToList(); 至 return dt.AsEnumerable()。Select(selector).ToList(); 因爲AsEnumerable是不在.Rows集合上的DataTable的擴展方法。 – AngryHacker 2009-05-15 04:44:26