收益率IEnumerable <ienumerable <...>&gt;

时间:2016-02-17 22:23:46

标签: c# linq deferred-execution

以下代码创建List<string>的中间实例,并在yield返回之前将值附加到它。有没有一种好方法可以避免创建实例并且直接返回单元格值?

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;
        }
    }
}

2 个答案:

答案 0 :(得分:7)

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

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

这将懒惰地执行,即不会创建任何中间列表。这是一种避免分配你不会需要的内存的简洁方法(除非你要在内部IEnumerable<string>上多次迭代,而getCellStr是昂贵的。)

答案 1 :(得分: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);
    }  
}