¿Cómo recorrer una colección que admite IEnumerable?

Respuestas:

155

Un regular para cada uno servirá:

foreach (var item in collection)
{
    // do your stuff   
}
Fredrik Mörk
fuente
Esto es más rápido que .ElementAt (). Desafortunadamente, mi voto está bloqueado en la respuesta de Alexa, por lo que no puedo deshacerlo, pero esta es la mejor respuesta. +1
Leo Gurdian
Entonces, ¿cómo se corrige la "posible enumeración múltiple de IEnumerable"?
SharpC
1
@SharpC: la forma más fácil es extraer el resultado en una List <T> o una matriz, y luego pasarlo a los distintos lugares que necesitan iterar sobre él. Esto garantiza que la enumeración (potencialmente cara) del resultado ocurre solo una vez, pero a costa de almacenar el resultado en la memoria. Mi primer paso sería averiguar si la enumeración múltiple es realmente un problema o no.
Fredrik Mörk
94

Junto con los métodos ya sugeridos para usar un foreachbucle, pensé que también mencionaría que cualquier objeto que implemente IEnumerabletambién proporciona una IEnumeratorinterfaz a través del GetEnumeratormétodo. Aunque este método generalmente no es necesario, se puede usar para iterar manualmente sobre colecciones y es particularmente útil cuando escribe sus propios métodos de extensión para colecciones.

IEnumerable<T> mySequence;
using (var sequenceEnum = mySequence.GetEnumerator())
{
    while (sequenceEnum.MoveNext())
    {
        // Do something with sequenceEnum.Current.
    }
}

Un buen ejemplo es cuando desea iterar sobre dos secuencias al mismo tiempo , lo que no es posible con un foreachbucle.

Noldorin
fuente
7
No olvide deshacerse del enumerador.
Eric Lippert
@Eric: Sí, lo agregaré porque es fácil pasarlo por alto.
Noldorin
1
Creo que solo funcionará para objetos IEnumerable <T> y no para IEnumerable. Tuve un caso genérico en el que tuve que convertir a IEnumerable y, por lo tanto, no tenía disponible el método GetEnumerator. Bueno para la mayoría de los casos de todos modos.
Fabio Milheiro
50

o incluso un método anticuado muy clásico

IEnumerable<string> collection = new List<string>() { "a", "b", "c" };

for(int i = 0; i < collection.Count(); i++) 
{
    string str1 = collection.ElementAt(i);
    // do your stuff   
}

tal vez también le gustaría este método :-)

Alexa Adrian
fuente
9
¿Por qué esto tiene tantos votos a favor? Esto enumerará las 2n veces enumerables en lugar de una.
Roman Reiner
1
@RomanReiner porque esto funciona, algunas personas no se preocupan por la actuación :)
Khateeb321
@RomanReiner este es un buen ejemplo, necesito asignar cada elemento de una colección a otra colección, creo que no puedo hacer esto usando foreach
AminM
1
Si observa la implementación de ElementAt, encontrará que si la colección es un IList, devuelven el elemento en el índice usando []; tan mismo rendimiento que [], sin embargo; si no, obtendrán Enumerator y comenzarán una iteración buscando secuencialmente el elemento antes de devolverlo, así que básicamente para cada elemento crean un nuevo enumerador y navegan por la lista nuevamente ...
Israel García
1
Es peor que todo eso, IEnumerable no es compatible con Count () o ElementAt (). Creo que está pensando en un ILista. En realidad, esto no responde a la pregunta en absoluto.
krowe
8
foreach (var element in instanceOfAClassThatImplelemntIEnumerable)
{

}
Darin Dimitrov
fuente
0

Quizás olvidaste la espera antes de devolver tu colección

Elialber Lopes
fuente