Kiedy użyłbyś List <KeyValuePair <T1, T2 >> zamiast Dictionary <T1, T2>?

96

Jaka jest różnica między listą KeyValuePair a słownikiem dla tych samych typów? Czy jest odpowiedni czas, aby użyć jednego lub drugiego?

Corpsekicker
źródło

Odpowiedzi:

81

Kiedy nie potrzebujesz szybkiego wyszukiwania klucza - utrzymanie tablicy hashy używanej przez Dictionaryma pewien narzut.

Pavel Minaev
źródło
9
Również operacja wstawiania listy jest szybsza niż ta w Słowniku
Vadym Stetsiak
2
Jego pola są przeznaczone tylko do odczytu, ale zawsze możesz zastąpić cały element na liście.
Pavel Minaev
Więcej różnic tutaj
Vinni
63

Krótko mówiąc, lista nie wymusza unikalności klucza, więc jeśli potrzebujesz tej semantyki, to powinieneś użyć.

RCIX
źródło
7
+1 Zauważ, że słownik również nie wymusza niepowtarzalności wartości!
gdoron wspiera Monikę
25

Słownik to typ ogólny, który zawiera kolekcję par klucz-wartość. Słownik jest szybki dla operacji wyszukiwania, ponieważ wewnętrznie używa funkcji skrótu . Oznacza to, że wszystkie klucze muszą być unikalne w słowniku .

Rozważ te przykłady:

List<KeyValuePair<int, string>> pairs = new List<KeyValuePair<int, string>>();
pairs.Add(new KeyValuePair<int, string>(1, "Miroslav"));
pairs.Add(new KeyValuePair<int, string>(2, "Naomi"));
pairs.Add(new KeyValuePair<int, string>(2, "Ingrid"));

Dictionary<int, string> dict = new Dictionary<int, string>();
dict.Add(1, "Miroslav");
dict.Add(2, "Naomi");
dict.Add(2, "Ingrid"); // System.ArgumentException: An item with the same key has already been added.

Dlatego zawsze powinieneś wziąć pod uwagę co najmniej dwie rzeczy:

  1. Chcesz przeszukać konkretne pozycje w słowniku?
  2. Czy chcesz, aby niektóre pola były nieunikalne (na przykład pary: imię / nazwisko).
Miroslav Holec
źródło
1
Myślę, że chodzi o to, że klucze słownika muszą być unikalne, podczas gdy klucze List <KeyValuePair> nie mogą być unikalne.
Bruno Bieri
6
@BrunoBieri List <KeyValuePair> klucze mogą nie być unikalne
Nikhil Vartak
2
Poprawiłem Twój komentarz sprzed 2 lat i zauważyłeś to. Nic dziwnego, że SO jest jedyną zaufaną i najpopularniejszą platformą pytań i odpowiedzi.
Nikhil Vartak
14

Lista byłaby również przydatna, gdy zależy Ci na kolejności przedmiotów.

nikt
źródło
2
Czy SortedDictionary nie obejmowałby tego?
Alex Angas
2
Tak, ale SortedDictionary nie może obejmować kolejności wartości, tylko klucze.
ConfusedMan
7

Zgodnie z odpowiedzią Phillipa Ngana, SOAP lub innym, nie można serializować XML obiektów, które implementują IDictionary.

P: Dlaczego nie mogę serializować tabel skrótów?

Odp .: XmlSerializer nie może przetwarzać klas implementujących interfejs IDictionary. Wynikało to częściowo z ograniczeń harmonogramu, a częściowo z faktu, że obiekt hashy nie ma odpowiednika w systemie typu XSD. Jedynym rozwiązaniem jest zaimplementowanie niestandardowej tablicy haszującej, która nie implementuje interfejsu IDictionary.

stąd

tjmoore
źródło
5

W usługach sieciowych SOAP dla Silverlight odkryliśmy, że Dictionary nie są serializowane. Byłaby to sytuacja, w której użyłbyś listy KeyValuePair zamiast słownika.

.

Phillip Ngan
źródło
3

Z http://blogs.msdn.com/bclteam/archive/2004/09/03/225473.aspx :

KeyValuePairkontra DictionaryEntry
[Krzysztof Cwalina]

Omówiliśmy problem z implementacją IEnumerableon Dictionary<K,V>. Jaki typ powinien IEnumerable.GetEnumerator().Current zwrócić? KeyValuePair<K,V>czy DictionaryEntry? To samo dotyczy ICollection.CopyTo. Wystąpienia jakiego typu należy skopiować do tablicy?

Zdecydowaliśmy, co następuje: IEnumerable i ICollectionimplementacje interfejsu będą używać KeyValuePair<K,V>jako typu elementu. IDictionaryokreśleni członkowie ( GetEnumeratorpowracający IDictionaryEnumerator) będą używać DictionaryEntryjako typu elementu.

Powodem jest to, że jesteśmy w trakcie wprowadzania zmian, które IEnumerator<T>mogłyby się rozszerzyć IEnumerator. Byłoby bardzo dziwne, gdybyśmy przechodząc po hierarchii od Dictionary<K,V>-> IEnumerable<T>-> IEnumerable nagle zmienili typ pozycji zwracanej z wyliczaczy.

Anax
źródło