2011-04-18 201 views
3

兩個問題在一個在這裏...泛型和繼承

我有一組從基類(稱爲RecordBase)繼承的DataRow包裝(在VS2008)的。他們都有一個名爲TableName的字段。我想製作一個泛型枚舉器,它是DataSet的擴展方法。特定的TableName將選擇要枚舉的DataSet中的哪個表。我想寫

public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase 
{ 
    foreach (DataRow row in MySet.Tables[T.TableName].Rows) 
    { 
     yield return new T(row); 
    } 
} 

問題1:我不能找到一種方法,有一個覆寫投放靜態字段,迫使我創建包裝的虛擬實例只是爲了讓表名。

問題2:儘管包裝器(和基礎)有一個接受DataRow的構造函數,但仍然堅持使用無參數構造函數約束,但不太嚴重。

所有這一切,讓我的代碼看起來像

public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase, new() 
{ 
    string TableName = (new T()).TableName; 

    foreach (DataRow row in MySet.Tables[TableName].Rows) 
    { 
     T record = new T(); 
     record.RowData = row; 
     yield return record; 
    } 
} 

任何想法?

回答

1

您可以使用自定義屬性表名和Activator實例類型:

[Table("Customers")] 
class Customer : RecordBase { } 

//... 
public static IEnumerable<T> GetRecords<T>(this DataSet MySet) where T : RecordBase 
{ 
    var attribT = typeof(TableAttribute); 
    var attrib = (TableAttribute) typeof(T).GetCustomAttributes(attribT,false)[0]; 

    foreach (DataRow row in MySet.Tables[attrib.TableName].Rows) 
    { 
     yield return (T) Activator.CreateInstance(typeof(T),new[]{row}); 
    } 
} 
+1

我已經忘記了自定義屬性。在上面的例子中,我需要用TableName替換TableAttribute,但它似乎工作。謝謝。 – 2011-04-20 04:45:41