Resharper's example code for explaining “Possible multiple enumeration of IEnumerable”

北慕城南 提交于 2019-11-26 15:36:51

问题


Sometimes Resharper warns about:

Possible multiple enumeration of IEnumerable

There's an SO question on how to handle this issue, and the ReSharper site also explains things here. It has some sample code that tells you to do this instead:

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

My question is about this specific suggestion: won't this still result in enumerating through the collection twice in the 2 for-each loops?


回答1:


GetNames() returns an IEnumerable. So if you store that result:

IEnumerable foo = GetNames();

Then every time you enumerate foo, the GetNames() method is called again (not literally, I can't find a link that properly explains the details, but see IEnumerable.GetEnumerator()).

Resharper sees this, and suggests you to store the result of enumerating GetNames() in a local variable, for example by materializing it in a list:

IEnumerable fooEnumerated = GetNames().ToList();

This will make sure that the GetNames() result is only enumerated once, as long as you refer to fooEnumerated.

This does matter because you usually want to enumerate only once, for example when GetNames() performs a (slow) database call.

Because you materialized the results in a list, it doesn't matter anymore that you enumerate fooEnumerated twice; you'll be iterating over an in-memory list twice.




回答2:


I found this to have the best and easiest way to understand multiple enumerations.

C# LINQ: Possible Multiple Enumeration of IEnumerable

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




回答3:


GetNames() is not called twice. The implementation of IEnumerable.GetEnumerator() is called each time you want to enumerate the collection with foreach. If within the IEnumerable.GetEnumerator() some expensive calculation is made this might be a reason to consider.




回答4:


Yes, you'll be enumerating it twice with no doubt. but the point is if GetNames() returns a lazy linq query which is very expensive to compute then it will compute twice without a call to ToList() or ToArray().



来源:https://stackoverflow.com/questions/20129079/resharpers-example-code-for-explaining-possible-multiple-enumeration-of-ienume

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!