Czy można bezpiecznie założyć, że dwie iteracje nad tą samą kolekcją zwrócą obiekty w tej samej kolejności? Oczywiście przyjmuje się, że zbiór nie został zmieniony w inny sposób.Czy porządek obiektów zwróconych przez FOREACH jest stabilny?
Odpowiedz
Krótka odpowiedź - tak.
Oczywiście, kolejność elementów w kolekcji może nie być dokładnie taka, jak zostały wstawione, w zależności od rodzaju kolekcji (na przykład słownik).
Ale otrzymasz te same wyniki za każdym razem, gdy będziesz sprawdzać jedną, niezmodyfikowaną kolekcję przy użyciu pętli foreach.
To zależy od rodzaju kolekcji. W przypadku większości kolekcji odpowiedź brzmi "Tak".
Jednak nie jest to gwarantowane. Dokumenty typu kolekcji powinny określać, czy to robi, czy nie, ale jak większość, szczegóły te są zwykle przeszukiwane. Jeśli jednak nie jest stabilny, byłoby to ogromnym niedopatrzeniem, gdyby doktorzy o tym nie wspomnieli.
Powiedziałbym, że w przypadku większości kolekcji można bezpiecznie to założyć. To nie jest poza sferą możliwości, że pewna kolekcja mogłaby mieć moduł wyliczający w sposób niedeterministyczny, ale to prawdopodobnie nie nastąpi ...
Zależy, czy chcesz mieć kod, który "prawdopodobnie" będzie działał. Osobiście lubię być bardziej pewny siebie! – MarkJ
Podczas gdy odpowiedź brzmi "tak" dla wszystkich kolekcji wbudowanych i prawdopodobnie każda klasa zbierania informacji na ten temat, dokumentacja nie ma żadnych ograniczeń sformułowanych dla IEnumerable
. Dlatego nic nie mówi nam, że każda iteracja musi być stabilna.
mogę sobie wyobrazić następujący przypadek użycia:
foreach (int i in new Shuffler(1, 2, 3, 4, 5, 6, 7, 8, 9))
Console.WriteLine(i);
To może być również realizowany jako klasa, która daje inny zamawiania dla każdej iteracji.
Więc - jeśli również rozważyć dziwne przypadki graniczne, odpowiedź powinna być „nr”.
Uh, czy James zmienił odpowiedź? Kiedy pisałem moje, było nadal oryginalne. : -/ –
Doskonały przykład przypadku, gdy zamówienie nie byłoby spójne! –
Chociaż zazwyczaj elementy zostaną zwrócone w tej samej kolejności, nie ma absolutnie żadnej gwarancji. Jest całkowicie zależny od wewnętrznej implementacji klasy kolekcji.
Widzę przypadek dla klasy kolekcji, która została specjalnie zaprojektowana do zwracania elementów w losowej kolejności, na przykład.
Podsumowując, jeśli nie znasz wewnętrznej implementacji klasy kolekcji, , nie należy przyjmować niczego o zamówieniu od.
Nie możesz tego zagwarantować, chyba że znasz konkretną implementację klasy, którą powtarzasz.
Kolekcje, które mają zdefiniowaną kolejność elementów (np. List<T>
) będą wyliczać w stabilnej kolejności.
W przypadku kolekcji, w których stan obiektu się nie zmienia, najprawdopodobniej elementy powrócą w tej samej kolejności, np. Dictionary<K,V>
, chociaż nie gwarantuje tego specyfikacja.
Jako przykład tego, gdzie nie jest to możliwe, można sobie wyobrazić implementację słownika opartego na haśle, która kompaktuje lub zmienia rozmiar tabeli asynchronicznie.Taka implementacja nie gwarantowałaby stabilnego zamówienia iteracyjnego.
Re "niezmodyfikowany" (odpowiedź NM) - zauważ, że wiele skomplikowanych pojemników, takich jak słownik, nie gwarantuje zachowania porządku. Czasami dodanie elementu sprawi, że pojawi się ono na końcu (sprawiając wrażenie, że zamówienie zostało zachowane), a czasami spowoduje ponowne uporządkowanie wewnętrznych segmentów, dając zupełnie inną kolejność.
Rzeczy takie jak SortedList <,> itd. Oczywiście mają swoje własne zasady.
Linq określa w tym celu interfejs IOrderedEnumerable.
hmmmm ... wydaje się, że obaj zrobiliśmy to samo. Napisz jedno zdanie, opublikuj je, a następnie natychmiast zredaguj, aby je rozwinąć. –
Rzeczywiście. Myślę, że twoja odpowiedź jest bardziej odpowiednia niż moja, mam nadzieję, że OP oznaczy ją jako ostateczną. Z pewnością wydaje się, że wygrywasz w popularnym głosowaniu :) –
Problem z oznaczeniem go jako ostateczną odpowiedzią, oczywiście, nie jest dokładny! –