2011-05-01 75 views
2

給定一個可能的5個項目的列表,下面的方法將返回一個新的確切5個項目的列表(如果原始列表少於5個,則添加更多項目)。這工作正常,但現在我需要重構它,以便它可以處理一個通用T列表(一個將具有相同的年份和Cnt屬性)。我怎樣才能將這個方法轉換成一個List並讓它返回一個帶有5個元素的新List?如何爲列表創建新的通用項目<T>?

private static List<FiveYearComplex> CreateFiveYearTemplate(int startYear, 
     int endYear, ObjectResult<FiveYearComplex> result) 
    { 
     var list = new List<FiveYearComplex>(5); 

     for (int year = startYear; year < endYear; ++year) 
     { 
      list.Add(new FiveYearComplex() { Year = year, Cnt = 0 }); 
     } 
     FiveYearComplex tmpItem; 
     foreach (var item in result) 
     { 
      tmpItem = list.Find(w => w.Year == item.Year); 
      if (tmpItem == null) 
      { 
       tmpItem = new FiveYearComplex() { Cnt = 0, Year = item.Year }; 
      } 
      else 
      { 
       tmpItem.Cnt = item.Cnt; 
      } 
     } 
     return list; 
    } 

當我嘗試使用List我終於碰到這個節:

for (int year = startYear; year < endYear; ++year) 
{ 
    list.Add(new T() { Year = year, Cnt = 0 }); 
} 

,我得到一個錯誤......

謝謝!

出於完整性:

public interface IYearTemplate 
    { 
     int? Year { get; set; } 
     decimal? Cnt { get; set; } 
    } 

    private static List<T> CreateFiveYearTemplate <T> (
     int startYear, int endYear, 
     ObjectResult<FiveYearAttendanceComplex> result) 
     where T : IYearTemplate, new() 
    { 
     var list = new List<T>(5); 

     for (int year = startYear; year < endYear; ++year) 
     { 
      list.Add(new T() { Year = year, Cnt = 0 }); 
     } 
     T tmpItem; 
     foreach (var item in result) 
     { 
      tmpItem = list.Find(w => w.Year == item.Year); 
      if (tmpItem == null) 
      { 
       tmpItem = new T() { Cnt = 0, Year = item.Year }; 
      } 
      else 
      { 
       tmpItem.Cnt = item.Cnt; 
      } 
     } 
     return list; 
    } 

謝謝你。

+0

你幾乎用回答了這個問題,就回到另一個 2011-05-01 20:12:22

+0

但是當我嘗試做新的T(){=年一年...我得到一個錯誤? – 2011-05-01 20:13:14

+0

你知道列表中的項目數量是基於'startYear'和'endYear'的值,而不是你以5的容量初始化列表的事實嗎? – juharr 2011-05-01 20:24:07

回答

4

(參數TE收盤)和Te方法體的開放{之間),你不能很容易地轉換你的方法來處理一個通用列表,因爲你的方法不是通用的。它要求列表中的每個項目具有屬性CntYear,因爲您的方法是通用的,您必須添加此約束。

public interface IYearTemplate 
{ 
    int Cnt {get;set;} 
    int Year {get;set;} 
} 

而且你的方法需要一個默認的構造函數,它表示爲約束new() - 所以它看起來是這樣的:

private static List<T> CreateFiveYearTemplate<T>(int startYear, 
    int endYear, ObjectResult<T> result) where T: IYearTemplate, new() 
{ 
    var list = new List<T>(5); 

    for (int year = startYear; year < endYear; ++year) 
    { 
     list.Add(new T() { Year = year, Cnt = 0 }); 
    } 
    T tmpItem; 
    foreach (var item in result) 
    { 
     tmpItem = list.Find(w => w.Year == item.Year); 
     if (tmpItem == null) 
     { 
      tmpItem = new T() { Cnt = 0, Year = item.Year }; 
     } 
     else 
     { 
      tmpItem.Cnt = item.Cnt; 
     } 
    } 
    return list; 
} 

說了,這種方法看起來不是很通用的,因爲約束條件是非常具體的。你爲什麼使它通用?

+0

好吧我刪除了所有領域詞彙表例子來保持它簡單,但我會有幾個實體需要返回一個5年和5個值(cnt)的列表。 – 2011-05-01 20:23:09

+0

我仍然不確定你的要求 - 你是否正在處理不同類型的列表,或者他們是否都返回'List ' - 如果後者是你不需要泛型的情況。 – BrokenGlass 2011-05-01 20:26:22

+0

謝謝你的回答。泛型非常有用!我確定。需要更熟悉它。 – 2011-05-01 20:32:22

3

對於爲任意T工作,你有兩個選擇:

  • 添加where T : SomeType約束,其中SomeType或者是一個基類或(更可能和更靈活的)的接口聲明的屬性你需要
  • 開關使用dynamic(或反射4.0之前)來訪問屬性

第一個給你編譯時的安全性,但需要一些常見T之間的差異;第二個要求沒有共同點,但是完全是運行時 - 沒有靜態分析檢查。

例如:

interface IRenameThis { 
    int Year {get;set;} 
    int Cnt {get;set;} 
} 

並添加where T : IRenameThis方法簽名

+0

謝謝你的解釋。我無法使用新的 – 2011-05-01 20:31:51

+0

@whatever - 哦,對 - 你需要在哪裏T:IRenameThis,new()'然後 - 注意'new()' – 2011-05-01 20:57:15

1
static List<T> CreateFiveYearTemplate(int startYear 
             ,int endYear 
             ,ObjectResult<T> result) 
     where T : FiveYearComplex, new() 
{ 
    ... 
} 
相關問題