2012-03-22 6 views
5

Szukałem w pewnym kodzie mój współpracownik zameldowaliśmy, wyglądało to tak:Dlaczego słownik .Net wygląda tak, jak jest posortowany?

return list.OrderBy(item => item.Order).ToDictionary(item => item.Id); 

razu powiedziałem mojemu współpracownikowi, że jego kod jest niewłaściwy, ponieważ Dictionary jest tabela hash, niebędącego -sortowana kolekcja. Powinien albo użyć kolekcji zachowującej porządek, albo posortować przedmioty później, czytając je ze słownika z foreach, powiedziałem.

Ale on odpowiedział "Nie, nie, mój kod jest poprawny! Słuchaj: teraz, gdy dodałem OrderBy, pozycje pojawiają się we właściwej kolejności."

Okazuje się, że w sprawie testowej miał rację. Próbowałem na innych danych, ale wciąż było idealnie posortowane!

Powiedziałem mu, że nie powinien polegać na tym zachowaniu, ale nie zgadza się on, i mam problemy z wyjaśnieniem dlaczego. Poza tym jestem zainteresowany tym, dlaczego zamówienie tak często wydaje się być zachowane.

Moje pytanie brzmi: Dlaczego Dictionary, zasadniczo nieposortowana kolekcja, wygląda tak bardzo, że jest posortowana?

+3

słownik <> nie daje gwarancji, że kolekcja jest nieuporządkowana . Nie używa Losowo celowo. Tak, kod jest nieprawidłowy. –

+1

tak Justin, to jest duplikat. Odpowiedź na pytanie, które łączysz, jest tym, czego pragnęłam. Jak szybko znaleźć duplikaty wśród tak wielu pytań na temat słowników? Szukałem i nie mogłem go znaleźć. Dziękuję Ci! –

+0

Nie wiem (dlatego zamieszczam to jako komentarz), ale wyobrażam sobie, że jest taki sam jak w SQL: wiersze zwrócone przez 'SELECT' są zwracane w nieokreślonej kolejności, chyba że dołączono klauzulę" ORDER BY " . Często, szczególnie w małych zestawach danych, wiersze są zwracane w takiej samej kolejności, w jakiej zostały wstawione, co powoduje przemieszczenie wielu osób. (Zawsze mówię ludziom, aby dodawali "ZAMÓWIENIE PRZEZ", jeśli w ogóle dbają o porządek wyników. * Może * działać bez niego, ale może również przerwać się strasznie.) –

Odpowiedz

6

To jest posortowana, ponieważ, jak Dictionary realizowany jest (aw przypadku swoje elementy są dodawane w kolejności). Ale to jest szczegóły implementacji.

poinformować współpracownika jest SortedDictionary klasa, która nie istnieje, to powinno się go przekonać, że nie można powoływać się na pozycji zamówić z prostym Dictionary;)

+0

Jest to szczegół implementacji, oczywiście, ale nie sądzę, że to się zmieni. Może dobrze jest powiedzieć, że tylko słowniki Add() zachowują porządek. –

+0

@EldritchConundrum Naprawdę, nie powinieneś tego zakładać. Obecnie tak jest, ale w przyszłej wersji może nie być. I pomyśl o innych implementacjach frameworka (na przykład Mono), nie ma gwarancji, że zaimplementowały słownik w ten sam sposób. – ken2k

+0

Tak. Co ważniejsze, teraz wiem, jak zbudować przypadek testowy, że kod mojego współpracownika zawodzi;) Po prostu muszę usunąć i dodać przed foreach. –

3

podczas iteracji nad słownikiem można dostać rzeczy w nim w the order they were inserted to the dictionary.

W tym przykładzie lista zostanie posortowana, a następnie każdy element zostanie dodany do słownika po kolei.

Rezultatem jest to, że pozycje w słowniku znajdują się w porządku sortowania listy.

Jednak tak się dzieje w przypadku obecnej wersji Dictionary - nie ma gwarancji, że pozostanie w ten sposób.

Jeśli musisz mieć pozycje w Dictionary w określonej kolejności, powinieneś używać SortedDictionary.

+0

Czy możesz wyjaśnić lepiej, dlaczego są one sortowane. Powiedziałbym, że są "uporządkowane" według ich skrótu, który jest własnością "Id" –

+1

@LuisFilipe - Nie śledzę. Lista została uporządkowana ('list.OrderBy (item => item.Order) 'następnie konwertowane na' Dictionary'. Konwersja działa poprzez dodanie każdego elementu do słownika. Pozycje w słowniku są "uporządkowane", ponieważ są w kolejności wstawiania. Ponieważ zostały one dodane w kolejności, słownik jest w porządku. – Oded

+0

Czy jest to zagwarantowane na podstawie specyfikacji/umowy, czy też jest to artefakt opisujący sposób wykonania określonej implementacji? Jeśli jest to zachowanie gwarantowane, przydatne byłoby przytoczenie. –

Powiązane problemy