2012-03-22 11 views
5

stavo guardando qualche codice mio collaboratore ha registrato, esso si presentava così:Perché il dizionario .Net sembra che sia ordinato?

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

ho subito detto al mio collega di lavoro che il suo codice è sbagliato, perché il Dictionary è una tabella hash, un non -serie assortite. Dovrebbe o usare una raccolta di conservazione degli ordini, o ordinare gli articoli più tardi mentre li legge dal dizionario con foreach, ho detto.

Ma lui ha risposto "No, no, il mio codice è corretto! Guarda: ora che ho aggiunto il OrderBy, gli articoli appaiono nell'ordine corretto."

Risulta, nel caso di test, aveva ragione. Ho provato su altri dati, ma era ancora perfettamente risolto!

Gli ho detto che non dovrebbe fare affidamento su questo comportamento, ma non è d'accordo, e ho difficoltà a spiegare perché. Inoltre, sono interessato al motivo per cui l'ordine sembra così spesso conservato.

Quindi la mia domanda è ... Perché la Dictionary, una raccolta fondamentalmente non ordinata, sembra tanto simile a come è ordinata?

+3

Dizionario <> non fornisce alcuna garanzia che la raccolta è ordinata . Di proposito, non usa Random. Sì, il codice è sbagliato. –

+1

sì Justin, questo è un duplicato. La risposta della domanda che hai collegato è ciò che volevo. Come puoi trovare i duplicati così velocemente tra così tante domande sui dizionari? Ho cercato e non ho potuto trovarlo. Grazie! –

+0

Non so (motivo per cui sto postando questo come commento) ma immagino che sia lo stesso di SQL: le righe restituite da 'SELECT' vengono restituite in ordine non specificato a meno che non sia inclusa una clausola' ORDER BY' . Spesso, in particolare in insiemi di dati di piccole dimensioni, le righe vengono restituite nello stesso ordine in cui sono state inserite, facendo scattare un sacco di persone. (Dico sempre alle persone di includere un "ORDER BY" se si preoccupano per l'ordine dei risultati. * Potrebbe * funzionare senza, ma potrebbe anche rompersi in modo orribile.) –

risposta

6

È ordinato, a causa di come è implementato (e nel tuo caso gli articoli vengono aggiunti in ordine). Ma questo è dettagli di implementazione.

Informi il collega di lavoro v'è una classe SortedDictionary che esiste, questo lo dovrebbe convincere non possiamo contare sugli articoli di ordine con una semplice Dictionary;)

+0

È un dettaglio di implementazione, certo, ma non credo che cambierà. Forse è giusto dire che Add() - solo i dizionari mantengono l'ordine. –

+0

@EldritchConundrum Davvero, non dovresti dare per scontato che. Attualmente è il caso, ma in una versione futura potrebbe non esserlo. E pensa ad altre implementazioni del framework (Mono per esempio), non c'è garanzia che abbiano implementato il dizionario allo stesso modo. – ken2k

+0

Sì. Ancora più importante, ora so come costruire un caso di test in cui il codice del mio collega fallirà;) Devo solo rimuovere e aggiungere prima del foreach. –

3

Durante l'iterazione su un dizionario si otterranno gli elementi in esso in the order they were inserted to the dictionary.

Nell'esempio, viene ordinato un elenco, quindi ogni voce viene aggiunta al dizionario a turno.

Il risultato finale è che gli elementi nel dizionario si trovano nell'ordine di ordinamento della lista.

Tuttavia, ciò si verifica solo con l'attuale implementazione di Dictionary - non è garantito che rimarrà tale.

Se è necessario disporre degli articoli in un Dictionary in un ordine specifico, è necessario utilizzare SortedDictionary.

+0

Puoi spiegare meglio perché sono ordinati. Direi che sono "ordinati" dal loro hash che è la proprietà "Id" –

+1

@LuisFilipe - Io non seguo. La lista è stata ordinata ('lista.OrderBy (item => item.Order) 'quindi convertito in un' Dictionary'. La conversione funziona aggiungendo ogni elemento al dizionario. Gli articoli nel dizionario sono "ordinati" in quanto sono in ordine di inserimento. Dato che erano _inseriti_ in ordine, il dizionario è in ordine. – Oded

+0

Questo è garantito dalla specifica/contratto o è un artefatto di come viene scritta una specifica implementazione? Se è garantito un comportamento, sarebbe utile una citazione. –

Problemi correlati