Como fazer um loop em uma coleção que oferece suporte a IEnumerable?


Respostas:


158

Um regular para cada fará:

foreach (var item in collection)
{
    // do your stuff   
}

Isso é mais rápido do que .ElementAt (). Infelizmente, meu voto está bloqueado na resposta de Alexa, então não posso desfazê-lo, mas esta é a melhor resposta. +1
Leo Gurdian

Então, como você corrige "Possível enumeração múltipla de IEnumerable"?
SharpC de

1
@SharpC: a maneira mais fácil é extrair o resultado em um List <T> ou array e, em seguida, passá-lo para os vários lugares que precisam iterar sobre ele. Isso garante que a enumeração (potencialmente cara) do resultado aconteça apenas uma vez, mas ao custo de armazenar o resultado na memória. Meu primeiro passo seria descobrir se a enumeração múltipla é realmente um problema ou não.
Fredrik Mörk de

94

Junto com os métodos já sugeridos de usar um foreachloop, pensei também em mencionar que qualquer objeto que implementa IEnumerabletambém fornece uma IEnumeratorinterface por meio do GetEnumeratormétodo. Embora esse método geralmente não seja necessário, ele pode ser usado para iterar manualmente sobre coleções e é particularmente útil ao escrever seus próprios métodos de extensão para coleções.

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

Um bom exemplo é quando você deseja iterar em duas sequências simultaneamente , o que não é possível com um foreachloop.


7
Não se esqueça de descartar o enumerador.
Eric Lippert,

@Eric: Sim, vou acrescentar porque é fácil de perder.
Noldorin,

1
Acho que só funcionará para objetos IEnumerable <T> e não para IEnumerable. Tive um caso genérico em que tive que converter para IEnumerable e, portanto, não tinha o método GetEnumerator disponível. Bom para a maioria dos casos de qualquer maneira.
Fabio Milheiro 18/06

51

ou mesmo um método muito clássico à moda antiga

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   
}

talvez você também queira este método :-)


9
Por que isso tem tantos votos positivos? Isso irá enumerar 2n vezes enumeráveis ​​em vez de uma vez.
Roman Reiner

1
@RomanReiner porque funciona, algumas pessoas não se preocupam com o desempenho :)
Khateeb321

@RomanReiner, este é um bom exemplo, preciso atribuir cada elemento de uma coleção a outra coleção, acho que não posso fazer isso usando foreach
AminM

1
Se você observar a implementação de ElementAt, descobrirá que se a coleção for um IList, eles retornam o elemento no índice usando []; tão mesmo desempenho que [], no entanto; caso contrário, eles obterão o Enumerador e iniciarão uma iteração sequencialmente procurando o elemento antes de retorná-lo, então, basicamente, para cada elemento, eles criam um novo enumerador e navegam na lista novamente ...
Israel Garcia

1
É pior do que tudo isso, IEnumerable não oferece suporte a Count () ou ElementAt (). Acho que ele está pensando em um ILista. Na verdade, isso não responde à pergunta.
krowe


Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.