可能存在IEnumerable的多次枚举?

15

在这里输入图片描述

为什么会这样?我该如何修复它?


1
除了最后一张截图和文字,其他都只是分散注意力,不是真正的问题。 - usr
1
这与https://dev59.com/VWw05IYBdhLWcg3wcRUj非常相似。Any()将计为一个枚举,而Aggregate()则为第二个。 - Bruno Silva
12
不要将代码以截图形式发布——请将源代码粘贴到问题中。 - Joe
1
这个问题之前在 StackOverflow 上已经被提出过 - 下面的两个问题可能会为您解释正在发生的情况:https://dev59.com/OGsy5IYBdhLWcg3w5CJr https://dev59.com/jmw15IYBdhLWcg3wd7lj - kaj
2个回答

18

这里没有需要修复的地方。 Any() 会遍历枚举,但在第一个元素之后停止(然后返回 true)。

多次枚举主要存在两个问题:

  • 性能:通常情况下,您希望避免多次迭代,因为速度较慢。但由于 Any() 只需确认是否至少存在一个元素,并且是必需的检查,因此在此情况下不适用。而且,您没有访问任何远程/外部资源,只是一个内存序列。

  • 不能迭代多次的枚举:例如从网络接收项等-在此情况下也不适用。

作为一个非 Linq 版本,只需要迭代一次,您可以执行以下操作:

bool foundAny= false;
bool isEqual = true;

if(f == null)
  throw new ArgumentException();

foreach(var check in f)
{
   foundAny = true;
   isEqual = isEqual && check(p,p2);
}

if(!foundAny)
  throw new ArgumentException();

return isEqual;

但是,正如注明的那样,在你的情况下这并没有什么区别,所以我会选择对你来说更可读的版本。


2
如果这是一个数据库查询,它将会执行两次,通常是完全地执行。 - usr
1
@usr:同意,我已经将其添加到第一个案例中 - 在这种情况下,它确实会有所不同,无论是远程/外部资源还是内存序列。 - BrokenGlass

6
Any方法可能会导致IEnumerable<T>的枚举,如果没有其他方法来确定结果。在某些情况下,这可能是一个问题,例如,如果IEnumerable<T>实例实际上是一个IQueryable<T>,那么将导致执行数据库查询或Web服务调用。现在,如果它只是一个内存中的集合,那么枚举集合并不会有显著的副作用,所以这并不是一个问题。而且,如果序列实现了ICollection<T>Any将使用Count属性,因此不会导致枚举。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接