Jak przeglądać kolekcję obsługującą IEnumerable?

Odpowiedzi:

155

Zwykły dla każdego zrobi:

foreach (var item in collection)
{
    // do your stuff   
}
Fredrik Mörk
źródło
Jest to szybsze niż .ElementAt (). Niestety mój głos jest ograniczony do odpowiedzi Alexy, więc nie mogę tego cofnąć, ale to najlepsza odpowiedź. +1
Leo Gurdian
Jak więc naprawić „Możliwe wielokrotne wyliczenie IEnumerable”?
SharpC
1
@SharpC: najprostszym sposobem jest wyciągnięcie wyniku do List <T> lub tablicy, a następnie przekazanie go do różnych miejsc, które wymagają iteracji. Gwarantuje to, że (potencjalnie kosztowne) wyliczenie wyniku nastąpi tylko raz, ale kosztem przechowywania wyniku w pamięci. Moim pierwszym krokiem byłoby ustalenie, czy wielokrotne wyliczanie rzeczywiście stanowi problem, czy nie.
Fredrik Mörk
94

Oprócz już sugerowanych metod używania foreachpętli, pomyślałem, że wspomnę również, że każdy obiekt, który implementuje, IEnumerablerównież zapewnia IEnumeratorinterfejs za pośrednictwem tej GetEnumeratormetody. Chociaż ta metoda zwykle nie jest konieczna, można jej użyć do ręcznego iterowania po kolekcjach i jest szczególnie przydatna podczas pisania własnych metod rozszerzających dla kolekcji.

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

Głównym przykładem jest sytuacja, w której chcesz wykonać iterację w dwóch sekwencjach jednocześnie , co nie jest możliwe w przypadku foreachpętli.

Noldorin
źródło
7
Nie zapomnij pozbyć się modułu wyliczającego.
Eric Lippert
@Eric: Tak, dodam to, ponieważ łatwo to przeoczyć.
Noldorin
1
Myślę, że to zadziała tylko dla obiektów IEnumerable <T>, a nie dla IEnumerable. Miałem ogólny przypadek, w którym musiałem rzutować na IEnumerable, dlatego nie miałem dostępnej metody GetEnumerator. W każdym razie miło w większości przypadków.
Fabio Milheiro
50

a nawet bardzo klasyczną staromodną metodę

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   
}

może spodobałaby Ci się również ta metoda :-)

Alexa Adrian
źródło
9
Dlaczego to ma tak wiele pozytywnych głosów? Spowoduje to wyliczenie wyliczalnych 2n razy zamiast raz.
Roman Reiner
1
@RomanReiner bo to działa, niektórzy nie zawracają sobie głowy występem :)
Khateeb321
@RomanReiner to dobry przykład, muszę przypisać każdy element jednej kolekcji do innej kolekcji, myślę, że nie mogę tego zrobić za pomocą foreach
AminM
1
Jeśli spojrzysz na implementację ElementAt, zauważysz, że jeśli kolekcja jest IList, zwracają element w indeksie przy użyciu []; jednak taka sama wydajność jak []; jeśli nie, dostaną Enumerator i rozpoczną iterację sekwencyjnie szukając elementu przed zwróceniem go, więc w zasadzie dla każdego elementu tworzą nowy moduł wyliczający i ponownie nawigują po liście ...
Israel Garcia
1
Co gorsza, IEnumerable nie obsługuje funkcji Count () ani ElementAt (). Myślę, że on myśli o ILista. To właściwie wcale nie odpowiada na pytanie.
krowe
8
foreach (var element in instanceOfAClassThatImplelemntIEnumerable)
{

}
Darin Dimitrov
źródło
0

Może zapomniałeś o czekaniu przed zwrotem kolekcji

Elialber Lopes
źródło