有时ReSharper的警告一下:IEnumerable的ReSharper的示例代码
的可能多个枚举
有an SO question on how to handle this issue,并ReSharper的网站也解释了事情here。它有一些示例代码,告诉你这样做,而不是:
IEnumerable<string> names = GetNames().ToList();
我的问题是关于这个具体建议:不会这还导致通过集合中的2-每个循环枚举两次?
有时ReSharper的警告一下:IEnumerable的ReSharper的示例代码
的可能多个枚举
有an SO question on how to handle this issue,并ReSharper的网站也解释了事情here。它有一些示例代码,告诉你这样做,而不是:
IEnumerable<string> names = GetNames().ToList();
我的问题是关于这个具体建议:不会这还导致通过集合中的2-每个循环枚举两次?
GetNames()
返回IEnumerable
。所以,如果你存储结果:
IEnumerable foo = GetNames();
然后每次枚举foo
时,GetNames()
方法再次被调用(不夸张地说,我无法找到一个链接,正确解释的细节,但看到IEnumerable.GetEnumerator()
)。
ReSharper的看到了这一点,并通过在列表中去实现它建议你存储在一个局部变量枚举GetNames()
,例如的结果:
IEnumerable fooEnumerated = GetNames().ToList();
这将确保该GetNames()
结果只列举一次,只要你参考fooEnumerated
。
这件事情确实是因为你通常要一次列举,例如当GetNames()
执行(慢)数据库调用。
因为你物化结果在列表中,你再次列举fooEnumerated
两次都没关系;您将两次遍历内存列表。
是的,你会毫无疑问地列举两次。但问题是,如果GetNames()
返回一个懒惰的LINQ查询这是计算则非常昂贵,将计算两次没有到ToList()
或ToArray()
通话。
GetNames()
不会被调用两次。每次您想要使用foreach
来枚举集合时,都会调用IEnumerable.GetEnumerator()
的实现。如果在IEnumerable.GetEnumerator()
内进行了一些昂贵的计算,这可能是一个需要考虑的原因。
我发现这是理解多个枚举的最好也是最简单的方法。
C#LINQ:IEnumerable的
的https://helloacm.com/c-linq-possible-multiple-enumeration-of-ienumerable-resharper/
你可以在这里指出你的链接的特殊点,但链接很不错 - > +1 – LuckyLikey
这是一个很好很容易解释的例子! – decompiled
啊可能的多个枚举!这解释了它。 – user2250250
否。只有在foreach循环中调用GetEnumerator()方法一次。真正的原因是脏数据的风险。例如,在GetNames()中,有一个SQL查询,但只有返回IEnurable的查询。当调用.ToList()时,将所有数据存储在内存中,脏数据的风险很小。但是如果在2次循环之间有很多时间,如果每次都对数据库执行SQL,那么脏数据的风险很大。 –
@SunRobin这是一个以简化形式呈现真相的答案,正如也在其中提到的那样。我还没有到处去改进它。您使用“脏数据”可能需要进一步解释。 – CodeCaster