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() 。