Quando useresti un List <KeyValuePair <T1, T2 >> invece di un Dictionary <T1, T2>?


95

Qual è la differenza tra un elenco di KeyValuePair e un dizionario per gli stessi tipi? C'è un momento appropriato per usare l'uno o l'altro?

Risposte:


80

Quando non sono necessarie ricerche rapide sulla chiave, il mantenimento della tabella hash utilizzata da Dictionaryha un certo overhead.


9
Anche l'operazione di inserimento dell'elenco è più veloce di quella nel Dizionario
— Vadym Stetsiak

2
I suoi campi sono di sola lettura, ma puoi sempre sostituire l'intero elemento nell'elenco.
— Pavel Minaev

Altre differenze qui
— Vinni

62

In breve, l'elenco non impone l'unicità della chiave, quindi se hai bisogno di quella semantica, allora è quello che dovresti usare.


7
+1 Nota che il dizionario non impone neanche l'unicità del valore!
— gdoron sostiene Monica l'

25

Il dizionario è un tipo generico che contiene una raccolta di coppie chiave-valore. Il dizionario è veloce per le operazioni di ricerca, perché utilizza internamente la funzione hash . Ciò significa che tutte le chiavi devono essere univoche nel dizionario .

Considera questi esempi:

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.

Quindi dovresti sempre considerare due almeno due cose:

  1. Vuoi cercare elementi concreti nel dizionario?
  2. Vuoi avere alcuni campi non univoci (ad esempio coppie: nome / cognome).

1
Penso che il punto qui sia che le chiavi del dizionario devono essere univoche dove le chiavi List <KeyValuePair> non devono essere univoche.
— Bruno Bieri

5
Le chiavi dell'elenco <KeyValuePair> di @BrunoBieri potrebbero non essere uniche
— Nikhil Vartak

2
Ho corretto il tuo commento di 2 anni e l'hai notato. Non c'è da stupirsi perché SO è l'unica piattaforma di domande e risposte affidabile e più popolare.
— Nikhil Vartak


7

Oltre alla risposta di Phillip Ngan, SOAP o altro, non è possibile serializzare XML oggetti che implementano IDictionary.

D: Perché non riesco a serializzare le tabelle hash?

R: XmlSerializer non può elaborare classi che implementano l'interfaccia IDictionary. Ciò è stato in parte dovuto a vincoli di pianificazione e in parte a causa del fatto che una tabella hash non ha una controparte nel sistema di tipo XSD. L'unica soluzione è implementare una tabella hash personalizzata che non implementa l'interfaccia IDictionary.

da qui


5

In SOAP webservices for silverlight, abbiamo scoperto che Dictionary's non serialize. Questa sarebbe una situazione in cui useresti un elenco di KeyValuePair su un dizionario.

.


3

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

KeyValuePaircontro DictionaryEntry
[Krzysztof Cwalina]

Abbiamo discusso un problema con l'implementazione di IEnumerableon Dictionary<K,V>. Che tipo deve IEnumerable.GetEnumerator().Current restituire? KeyValuePair<K,V>o DictionaryEntry? Lo stesso per ICollection.CopyTo. Istanze di che tipo devono essere copiate nell'array?

Abbiamo deciso quanto segue: IEnumerable e le ICollectionimplementazioni dell'interfaccia utilizzeranno KeyValuePair<K,V>come tipo di elemento. IDictionarymembri specifici (di GetEnumeratorritorno IDictionaryEnumerator) utilizzeranno DictionaryEntrycome tipo di elemento.

Il motivo è che siamo in procinto di apportare un cambiamento in cui IEnumerator<T>si estenderebbe IEnumerator. Sarebbe molto strano se percorrendo la gerarchia da Dictionary<K,V>-> IEnumerable<T>-> IEnumerable cambiassimo improvvisamente il tipo di elemento restituito dagli enumeratori.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.