Reputation: 29159
The following code creates an intermediate instance of List<string>
and append values to it before yield return it. Is there a good way to avoid creating the instance and yield return the cell values directly?
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;
}
}
}
Upvotes: 2
Views: 1355
Reputation: 51204
To avoid creating the list, you can use LINQ:
IEnumerable<IEnumerable<string>> GetStrValues()
{
return rows.Select(r => r.Cells().Select(getCellStr));
}
This will execute lazily, i.e. no intermediate list will be created. It's a neat way to avoid allocating memory you won't be needing (unless you are going to iterate several times over the inner IEnumerable<string>
, and getCellStr
is expensive).
Upvotes: 7
Reputation: 127543
You can get deffered action per cell by using two functions.
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);
}
}
Upvotes: 4