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