2009-07-08 30 views
12

我碰到了一個問題,我根本無法找到一個好的解決方法。方法重載只有通用約束不同

我想有這3個重載:

public IList<T> GetList<T>(string query) where T: string 
public IList<T> GetList<T>(string query) where T: SomeClass 
public IList<T> GetList<T>(string query) where T: struct 

顯然,第一個約束甚至不會單獨編譯,所以這是我的第一個問題。 (我知道我可以讓它成爲IList,但我希望三種語法的語法相同)

無論如何,所有這些的原因是這些方法是對數據庫執行SQL查詢的一部分包裝 - 我想成爲能夠返回結果作爲字符串列表(如果有人選擇了一個varchar列),一系列的值類型(int,float,whatever)或者一個類的列表(這些類代表表格,因此包含多列)

我希望這部分有點可以理解:-)

無論如何,我的大問題顯然是我不能做這些重載,因爲他們使用相同的名稱和參數列表。

我也無法將它們合併到同一個方法,因爲我需要調用SomeClass的一個方法在執行,所以,除非我想要做一些繁重的類型轉換,或者更糟糕,反思 - 我需要約束。

我意識到我想要做的事情是不可能的,所以我在尋找的是一個很好的方法,它會模仿我的意圖。

如果一些,這是一個有點不清楚,請隨時問:-)

編輯:

這裏是我的「其中T:SomeClass的」當前代碼版本。我想字符串/值類型支持添加到這個當前的代碼,所以也許我最初的做法是完全錯誤的 - 任何想法,歡迎基本上:-)

public IList<TValue> GetList<TValue>(string query) where TValue : DbTable, new() 
{ 
    DataSet dataSet = GetDataSet(query); 
    IList<TValue> result = new List<TValue>(); 

    if (dataSet.Tables.Count > 0) 
    { 
     foreach (DataRow row in dataSet.Tables[0].Rows) 
     { 
      TValue col = new TValue(); 
      col.Fill(row); 
      result.Add(col); 
     } 
    } 

    return result; 
} 

正如你可以看到我所需要的確切類型DbTable爲了創建正確的構造函數。填充是DbTable(這是一個抽象類)的抽象方法。

回答

10

正如你所說;這沒有任何好的選擇。你可能會考慮不同的名稱(而不是過載) - GetStringList

但是,我不知道是否會更簡單地刪除約束。用「as」進行單個類型檢查並不完全是「重」的類型轉換,它可能會節省很多痛苦。

+0

是不同的名字很簡單,但是我想讓它幾乎一樣,如果它只是一個相同的方法,即acceps這些約束。 我可以做一個GetList 沒有約束,然後拋出一個異常,如果類型是錯誤的 - 但在SomeClass的情況下,它實際上是繼承SomeClass的類,我需要確切的類型,因爲我new()他們。 掛在秒,我會張貼我現有的GetList 其中T:SomeClass代碼。 – Steffen 2009-07-08 11:47:31

+0

在這種情況下,它可能會混亂`MakeGenericMethod`等;不是一個好的選擇。 – 2009-07-08 11:51:06

0

這是怎麼回事?

public IList<T> GetList<T>(string query) where T : new() 
{ 
    // whatever you need to distinguish, this is a guess: 
    if (typeof(T).IsPrimitiveValue) 
    { 
    GetPrimitiveList<T>(query); 
    } 
    else if (typeof(T) == typeof(string)) 
    { 
    GetStringList<T>(query); 
    } 
    else 
    { 
    GetEntityList<T>(query); 
    } 

} 

private IList<T> GetStringList<T>(string query) 

private IList<T> GetPrimitiveList<T>(string query) 

private IList<T> GetEntityList<T>(string query)