Dlaczego w .net nie ma ogólnej implementacji OrdersDictionary?

26

Dlaczego firma Microsoft nie zapewniła ogólnej implementacji narzędzia OrdersDictionary?

Widziałem kilka niestandardowych implementacji, w tym: http://www.codeproject.com/KB/recipes/GenericOrdersDictionary.aspx

Ale dlaczego Microsoft nie zawarł go w podstawowej bibliotece .net? Z pewnością mieli powód, by nie budować generycznego ... ale co to jest?

Przed opublikowaniem tej wiadomości widziałem: /programming/2629027/no-generic-implementation-of-ordereddictionary

Ale to tylko potwierdza, że ​​nie istnieje. Nie, dlaczego to nie istnieje.

Dzięki

nonot1
źródło
2
Zawsze jest SortedDictionary<TKey, TValue>: msdn.microsoft.com/en-us/library/f7fta44c.aspx
Travis Gockel
2
Chyba że źle zrozumiem dokumenty SortedDict, nie tego chcę. Nie chcę żadnego sortowania. Chcę tylko tablicy, do której mogę również uzyskać dostęp za pomocą klucza. W każdym razie, naprawdę zastanawiam się, dlaczego stwardnienie rozsiane to pominęło. (Subtelne problemy itp.)
non1 1
Jaki jest typowy przypadek użycia uporządkowanego słownika? Z trudem przychodzi mi na myśl jedno z góry.
Carson63000,
1
@Carson za każdym razem, gdy masz szereg elementów danych, do których potrzebujesz również szybkiego, losowego dostępu. Zwykłe przechowywanie w Dict traci informacje dotyczące zamawiania, a korzystanie z tablicy wymaga zachowania własnego indeksu.
nonot1
2
Poproś Erica Lipperta o przeczytanie i odpowiedź na twoje pytanie. Zazwyczaj bardzo chętnie pomaga z tego typu pytaniami. Myślę, że możesz skontaktować się z nim za pośrednictwem jego bloga: blogs.msdn.com/b/ericlippert
devuxer

Odpowiedzi:

17

W C # 4.0 W pigułce czytam to:

  1. An OrderedDictionaryjest kombinacją a HashTableiArrayList
  2. Nie ma ogólnego ArrayList
  3. ArrayListKlasa nieogólna jest używana głównie ze względu na kompatybilność wsteczną z Framework 1.x ...”
  4. „Funkcja ArrayListjest funkcjonalnie podobna do List<object>
  5. „Odbicie jest łatwiejsze ArrayListniż nieogólne niż List<object>

Wniosek?

Żadna ogólna, OrderedDictionaryponieważ jej podstawowa konstrukcja jest (nieoficjalnie) zdeprecjonowaną klasą, która nie ma samej wersji ogólnej.

radarbob
źródło
4
To tak naprawdę nie odpowiada na pytanie. Ogólny OrDERDictionary można oczywiście zbudować na ogólnym słowniku i ogólnej liście.
JacquesB
Jedną z zasad używania klas jest to, że interfejs użytkownika nie zmienia, kogo obchodzi implementacja? Cóż, zespół projektowy / kompilator języka, powiedzmy, może preferować rodzajowe dziedziczące jego nie-ogólny odpowiednik . Moje pająkowate zmysły drżą. Na początek: czy różni (bezpośredni) przodek jest kopalnią ziemi gdzieś na ścieżce ewolucji pod kątem OrderedDictionarykowariancji i wariancji kontra?
radarbob
15

Do OrderedDictionaryprzeciążenia operacja indeksowania tak że indeksowanie z całkowitą Ndostanie element w pozycji N, podczas indeksowania ze związkiem Objectbędzie odzyskać pozycję coresponding do tego obiektu. Gdyby stworzyć OrderedDictionary<int, string>nazywa myDicti dodał egzemplarze (1, „George”) i (0, „Fred”) w tej kolejności, należy myDict[0]wrócić „George” lub „Fred”?

Taki problem można rozwiązać, nakładając ograniczenie klasy na typ klucza. Z drugiej strony duża część użyteczności zbiorów ogólnych wynika z ich zdolności do wydajnej pracy z typami wartości. Nałożenie ograniczenia klasowego na typ klucza wydaje się trochę brzydkie.

Gdyby klasa nie musiała być zgodna z CLS, ale po prostu musiała współpracować z vb.net, rozsądnym projektem mogłoby być użycie nazwanych właściwości indeksowanych. Tak więc w powyższym przykładzie myDict.ByKey[0]dałbym „Fred”, a myDict.BySequence[0]dałby „George”. Niestety, języki takie jak C # nie obsługują nazwanych indeksowanych właściwości. Podczas gdy można było zakłócać coś, co pozwala na użycie powyższej składni, nawet bez takich właściwości, niefortunna decyzja o zawinięciu pól struktur takich jak Pointi Rectangleoznacza, że myDict.ByKey[0] = "Wally"aby działać, myDict.ByKeymusiałaby zwrócić obiekt nowej klasy. Struktura byłaby bardziej wydajna, ale kompilatory odrzuciłyby coś, co wyglądało jak zapis do struktury tylko do odczytu (mimo że właściwość nie zmodyfikowałaby struktury zwróconej przezByKey, ale zamiast tego zmodyfikuj kolekcję, do której zawiera odwołanie).

Osobiście uważam, że dobrze byłoby mieć słownikowy obiekt, który został określony jako śledzenie kolejności wstawiania; Chciałbym również mieć obiekt słownikowy, który mógłby łatwo zwrócić klucz powiązany z określonym kluczem (tak, że np. Jeśli ktoś ma słownik bez rozróżniania wielkości liter i dodał rekord z kluczem „GEORGE”, jeden może zapytać słownik, który klucz jest powiązany z „George”, bez konieczności przeszukiwania wszystkich KeyValuePairobiektów zwróconych w wyliczeniu.

supercat
źródło
3

Ponieważ utrzymanie porządku uniemożliwia wyszukiwanie w O (1), które implikuje IDictionary, chyba że opakujesz dwie kolekcje (jedna dla porządku, jedna dla wyszukiwania), co powoduje, że dodawanie / usuwanie jest mniej wydajne i zwiększa użycie pamięci. Lub możesz mieć wolniejsze wyszukiwanie w zamian za mniejsze zużycie pamięci.

Domyślam się, że nie było tutaj „wyraźnie lepszego” wyboru, więc nie poszedł do standardowej biblioteki. Zwłaszcza około 2.0, C # wciąż uczył się na błędach Javy. Nie zdziwiłbym się, gdyby podejście Java do „wszystkiego i zlewu kuchennego” do kolekcji w ich standardowej bibliotece również było postrzegane jako coś, czego należy unikać.

Telastyn
źródło
1
Wolniejsze wyszukiwanie w zamian za mniej pamięci tylko skutecznie sprawia, że OrderedDictionarya List. Wyobrażam sobie, że każdy, kto ma uzasadniony przypadek użycia dla, OrderedDictionaryużywa go konkretnie, ponieważ potrzebuje klasy kolekcji, która ma wyszukiwanie O (1), ale także pamięta kolejność wstawiania, w którym to przypadku użycie dodatkowej pamięci jest nieuniknione, a zatem dopuszczalne.
Abion47,