Resharper用于解释“IEnumerable可能的多个枚举”的示例代码

有时,Resharper警告:

可能的多重IEnumerable枚举

如何处理这个问题有一个问题 ,ReSharper网站也在这里解释一些事情。 它有一些示例代码,告诉你这样做:

IEnumerable<string> names = GetNames().ToList(); 

我的问题是关于这个具体的build议:这两个循环中是不是还会通过两次枚举来枚举呢?

GetNames()返回一个IEnumerable 。 所以,如果你存储的结果:

 IEnumerable foo = GetNames(); 

然后每次枚举foo ,都会再次调用GetNames()方法(而不是字面上,我找不到正确解释详细信息的链接,但请参阅IEnumerable.GetEnumerator() )。

Resharper看到了这一点,并build议您将枚举GetNames()结果存储在本地variables中,例如通过在列表中实现GetNames()

 IEnumerable fooEnumerated = GetNames().ToList(); 

这将确保GetNames()结果只枚举一次,只要您引用fooEnumerated

这很重要,因为您通常只想枚举一次,例如GetNames()执行(慢)数据库调用时。

因为你在一个列表中实现了结果,所以枚举fooEnumerated两次并不重要; 你将遍历一个内存列表两次。

我发现这是理解多个枚举最好也是最简单的方法。

C#LINQ:可能的枚举IEnumerable

https://helloacm.com/c-linq-possible-multiple-enumeration-of-ienumerable-resharper/

GetNames()不会被调用两次。 IEnumerable.GetEnumerator()的实现在每次你想用foreach枚举集合的时候被调用。 如果在IEnumerable.GetEnumerator()一些昂贵的计算,这可能是一个考虑的理由。

是的,你会毫无疑问地列举两次。 但重点是如果GetNames()返回一个懒惰的linq查询,这是非常昂贵的计算,然后它将计算两次,而无需调用ToList()ToArray()