为 public 方法生成 return 反模式?
Yield return for a public method an anti-pattern?
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)
迭代。
问题
class 是否有责任仅公开 O(n)
个枚举器,我是否希望在 returning 'yielded' 之前总是调用 ToList() IEnumerable
?
当用户只想迭代一次时调用 unnessary ToList()
的(小)缺点?
或者我应该把这个决定留给这个 class 的用户,让他们决定是否要 ToList
在迭代之前得到结果?
假设我们谈论的是高性能环境。
如果用户知道需要对返回的集合进行多次枚举并且不想重新计算值。
在这些情况下,ReSharper 甚至会显示警告。
此外,将决定下推给调用者可以提供更大的灵活性,因为在某些情况下,您不受 CPU 的限制,但会受到内存使用的限制,您可以这样做额外计算以防止发生额外分配。
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)
迭代。
问题
class 是否有责任仅公开 O(n)
个枚举器,我是否希望在 returning 'yielded' 之前总是调用 ToList() IEnumerable
?
当用户只想迭代一次时调用 unnessary ToList()
的(小)缺点?
或者我应该把这个决定留给这个 class 的用户,让他们决定是否要 ToList
在迭代之前得到结果?
假设我们谈论的是高性能环境。
如果用户知道需要对返回的集合进行多次枚举并且不想重新计算值。
在这些情况下,ReSharper 甚至会显示警告。
此外,将决定下推给调用者可以提供更大的灵活性,因为在某些情况下,您不受 CPU 的限制,但会受到内存使用的限制,您可以这样做额外计算以防止发生额外分配。