2016-02-17 176 views
2

以下代碼創建一箇中間實例List<string>並在yield返回之前向其添加值。有沒有避免創建實例並直接返回單元格值的好方法?產量返回IEnumerable <IEnumerable <...>>

IEnumerable<IEnumerable<string>> GetStrValues() 
{ 
    ...... 
     foreach (var r in rows) 
     { 
      var row = new List<string>(); 
      foreach (var c in r.Cells()) 
      { 
       var value = getCellStr(c); 
       row.Add(value); 
      } 
      yield return row; 
     } 
    } 
} 

回答

7

要避免創建列表,你可以使用LINQ:

IEnumerable<IEnumerable<string>> GetStrValues() 
{ 
    return rows.Select(r => r.Cells().Select(getCellStr)); 
} 

這會懶洋洋地執行,即,沒有中間名單將被創建。這是避免分配你不需要的內存的一種很好的方法(除非你要在內部IEnumerable<string>上迭代幾次,並且getCellStr是昂貴的)。

+0

奇怪的是,如果我想平坦的結果爲'IEnumerable ',我應該改變第一個'.Select('到'.SelectMany('? – ca9163d9

+0

@ dc7a9163d9:是的,這正是'SelectMany'是for,並且仍然使用延遲執行,所以這就是你應該用來如果你的意圖是平坦的結果。 – Groo

4

您可以通過使用兩個函數獲得每個單元格的緩存操作。

IEnumerable<IEnumerable<string>> GetStrValues() 
{ 
    ...... 
     foreach (var r in rows) 
     { 
      yield return GetCellValues(row); 
     } 
    } 
} 

IEnumerable<string> GetCellValues(Row r) 
{ 
    foreach (var c in r.Cells()) 
    { 
     yield return getCellStr(c); 
    } 
} 
+0

「這是避免創建實例並直接返回單元格值的好方法嗎?」這是一個問題,他已經建議這樣做 –

+0

我認爲他不是英語母語的人,他試圖說「***有沒有一種好方法可以避免創建實例並返回單元格值直接?「,但也許我錯了。 –

+0

他編輯了這個問題,我的歉意 –

相關問題