c# resharper resharper-7.1

c# - Código de ejemplo de Resharper para explicar "Posible enumeración múltiple de IEnumerable"



resharper-7.1 (4)

A veces, Resharper advierte sobre:

Posible enumeración múltiple de IEnumerable

Hay una pregunta de SO sobre cómo manejar este problema , y el sitio ReSharper también explica las cosas here . Tiene algún código de ejemplo que te dice que hagas esto en su lugar:

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

Mi pregunta es sobre esta sugerencia específica: ¿esto aún no resultará en la enumeración a través de la colección dos veces en los 2 bucles para cada uno?



Sí, lo vas a enumerar dos veces sin duda alguna. pero el punto es si GetNames() devuelve una consulta de linq perezosa que es muy costosa de calcular, entonces se computará dos veces sin una llamada a ToList() o ToArray() .


GetNames() devuelve un IEnumerable . Así que si almacenas ese resultado:

IEnumerable foo = GetNames();

Luego, cada vez que se enumera foo , se vuelve a llamar al método GetNames() (no literalmente, no puedo encontrar un enlace que explique correctamente los detalles, pero vea IEnumerable.GetEnumerator() ).

Resharper ve esto y le sugiere que almacene el resultado de enumerar GetNames() en una variable local, por ejemplo materializándolo en una lista:

IEnumerable fooEnumerated = GetNames().ToList();

Esto asegurará que el resultado GetNames() solo se enumere una vez, siempre que se refiera a fooEnumerated .

Esto es importante porque normalmente solo desea enumerar una vez, por ejemplo, cuando GetNames() realiza una llamada de base de datos (lenta).

Debido a que materializó los resultados en una lista, ya no importa que enumere fooEnumerated dos veces; estará iterando sobre una lista en memoria dos veces.


GetNames() no se llama dos veces. La implementación de IEnumerable.GetEnumerator() se llama cada vez que desea enumerar la colección con foreach . Si dentro de IEnumerable.GetEnumerator() algún cálculo costoso, esta podría ser una razón para considerar.