Często spotykam się z tym podczas programowania, w którym chcę mieć indeks liczby pętli w foreach i muszę utworzyć liczbę całkowitą, użyć go, zwiększyć itd. Czy nie byłoby dobrym pomysłem, gdyby wprowadzono słowo kluczowe, które było liczba pętli w foreach? Może być również używany w innych pętlach.
Czy stoi to w sprzeczności ze stosowaniem słów kluczowych, ponieważ kompilator nie pozwala na użycie tego słowa kluczowego nigdzie indziej niż w konstrukcji pętli?
for ()
pętli.Odpowiedzi:
Jeśli potrzebujesz liczby pętli w
foreach
pętli, skorzystaj z zwykłejfor
pętli.foreach
Pętlowy przeznaczone do specyficznych zastosowańfor
pętli prostsze. Wygląda na to, że masz sytuację, w której prostotaforeach
nie jest już korzystna.źródło
IEnumerable.Count
może być kosztowny (lub niemożliwy, jeśli jest to jednorazowe wyliczenie). Musisz wiedzieć, jakie jest podstawowe źródło, zanim będziesz mógł to zrobić bezpiecznie.foreach
ponadfor (int i = 0…)
. Napisał kilka stron, ale mogę streścić w dwóch słowach - optymalizacja kompilatora podczas iteracji. Ok, to nie były dwa słowa.for
pętla daje lepiej czytelny kod (a teoretyczna optymalizacja kompilatora jest często przedwczesną optymalizacją).Możesz użyć takich anonimowych typów
Jest to podobne do
enumerate
funkcji Pythonaźródło
Właśnie dodam tutaj odpowiedź Dana Fincha , zgodnie z prośbą.
Nie dawaj mi punktów, dawaj punkty Danowi Finchowi :-)
Rozwiązaniem jest napisanie następującej ogólnej metody rozszerzenia:
Który jest używany tak:
źródło
Mogę się mylić, ale zawsze myślałem, że głównym celem pętli foreach było uproszczenie iteracji z dni STL C ++, tj.
porównaj to do użycia IEnumerable w .NET w foreach
ten drugi jest o wiele prostszy i pozwala uniknąć wielu starych pułapek. Ponadto wydają się przestrzegać prawie identycznych zasad. Na przykład nie można zmienić zawartości IEnumerable wewnątrz pętli (co ma o wiele większy sens, jeśli myślisz o tym w sposób STL). Pętla for ma jednak często inny logiczny cel niż iteracja.
źródło
for(IEnumerator e=collection.GetEnumerator;e.MoveNext();) { ... }
Jeśli chodzi o kolekcję
IList<T>
, możesz po prostu użyć jejfor
do indeksowania:Jeśli nie, to możesz użyć
Select()
, ma przeciążenie, które daje indeks.Jeśli to również nie jest odpowiednie, myślę, że ręczne utrzymanie tego indeksu jest dość proste, to tylko dwie bardzo krótkie linie kodu. Utworzenie słowa kluczowego specjalnie w tym celu byłoby przesadą.
źródło
foo(++i)
lub wfoo(i++)
zależności od tego, który indeks jest potrzebny.Jeśli wszystko, co wiesz, to, że kolekcja jest IEnumerable, ale musisz śledzić, ile elementów przetworzyłeś do tej pory (a tym samym sumę po zakończeniu), możesz dodać kilka linii do podstawowej pętli for:
Możesz także dodać przyrostową zmienną indeksu do foreach:
Jeśli chcesz, aby wyglądał bardziej elegancko, możesz zdefiniować metodę rozszerzenia lub dwie, aby „ukryć” te szczegóły:
źródło
Scoping działa również, jeśli chcesz utrzymać blok w czystości przed kolizjami z innymi nazwami ...
źródło
Do tego używam
while
pętli. Pętlefor
również działają, i wydaje się, że wiele osób je preferuje, ale lubię używać tylkofor
z czymś, co będzie miało określoną liczbę iteracji.IEnumerable
s mogą być generowane w czasie wykonywania, więc moim zdaniemwhile
ma to większy sens. Jeśli chcesz, nazwij to nieformalną wytyczną kodowania.źródło