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?
GetNames()
returns anIEnumerable
. So if you store that result:Then every time you enumerate
foo
, theGetNames()
method is called again (not literally, I can't find a link that properly explains the details, but seeIEnumerable.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:This will make sure that the
GetNames()
result is only enumerated once, as long as you refer tofooEnumerated
.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.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 toToList()
orToArray()
.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/
GetNames()
is not called twice. The implementation ofIEnumerable.GetEnumerator()
is called each time you want to enumerate the collection withforeach
. If within theIEnumerable.GetEnumerator()
some expensive calculation is made this might be a reason to consider.