2016-02-17 175 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

他编辑了这个问题,我的歉意 –

相关问题