yield return是一种非常好的语法,可以快速编写过滤器或映射,这些过滤器或映射对于使用Linq语句来说太过分了。这就是为什么我经常写这样的方法:
public IEnumerable<Person> GetFilteredPersons()
{
foreach ( var person in _Persons )
{
// [Semi-expensive logic]
yield return person;
}
}
问题是这个方法的用户不知道当他在obj.GetFilteredPersons()
上多次迭代时,他正在浪费不必要的CPU。它甚至可能意味着当他认为他正在进行两次简单的O(n)
迭代时,他实际上进行了两次O(n^2)
次迭代。
问题
该类是否有责任仅公开O(n)
个枚举器,我希望在返回'yielding'IEnumerable
之前总是调用ToList()?
当用户只想迭代一次时,调用一个ToList()
的(小)缺点?
或者我应该将此决定留给本课程的用户,并让他们在迭代之前决定是否要ToList
结果?
假设我们正在讨论高性能环境。
答案 0 :(得分:12)
如果用户知道它需要多次枚举返回的集合并且不想重新计算,那么用户有责任调用ToList()
从声明为返回IEnumerable<T>
的方法返回的值。值。
在这些情况下,甚至会有ReSharper显示的警告。
此外,将决策推送给调用者可以提供更大的灵活性,因为在某些情况下,您不会受到CPU的限制,但是您会限制内存使用,并且您可以做额外的计算,以防止发生额外的分配。