hashtable vs dictionary c#
Perché il dizionario è preferito su Hashtable? (12)
Cordiali saluti: In .NET, Hashtable
è thread-safe per l'utilizzo da più thread di lettura e un singolo thread di scrittura, mentre nel Dictionary
i membri statici pubblici sono thread-safe, ma i membri di ogni istanza non sono garantiti come thread-safe.
Abbiamo dovuto cambiare tutti i nostri dizionari di Hashtable
causa di questo.
Nella maggior parte dei linguaggi di programmazione, i dizionari sono preferiti rispetto agli hashtables. Quali sono le ragioni dietro a questo?
In .NET, la differenza tra Dictionary<,>
e HashTable
è principalmente che il primo è un tipo generico, quindi ottieni tutti i vantaggi dei generici in termini di controllo del tipo statico (e boxing ridotto, ma non è così grande come le persone tendono a pensare in termini di prestazioni - anche se il costo della boxe è definito in modo definitivo).
Le persone dicono che un dizionario è lo stesso di una tabella hash.
Questo non è necessariamente vero. Una tabella hash è un'implementazione di un dizionario. Un tipico a quello, e potrebbe essere quello predefinito in. NET, ma non è per definizione l'unico.
Potresti ugualmente implementare un dizionario con un elenco collegato o un albero di ricerca, ma non sarebbe altrettanto efficiente (per alcuni parametri di efficienza).
Per quello che vale, un dizionario è (concettualmente) una tabella hash.
Se intendevi "perché usiamo la classe Dictionary<TKey, TValue>
invece della classe Hashtable
?", Allora è una risposta facile: il Dictionary<TKey, TValue>
è un tipo generico, Hashtable
no. Ciò significa che si ottiene la sicurezza del tipo con Dictionary<TKey, TValue>
, perché non è possibile inserire alcun oggetto casuale in esso e non è necessario eseguire il cast dei valori che si estrapolano.
È interessante notare che l'implementazione del Dictionary<TKey, TValue>
in .NET Framework è basata su Hashtable
, come si può notare da questo commento nel suo codice sorgente:
Il dizionario generico è stato copiato dalla fonte di Hashtable
Poiché .NET Framework 3.5 include anche un HashSet<T>
che fornisce tutti i vantaggi del Dictionary<TKey, TValue>
se sono necessarie solo le chiavi e nessun valore.
Pertanto, se si utilizza un Dictionary<MyType, object>
e si imposta sempre il valore su null
per simulare il tipo hash table sicuro, è consigliabile prendere in considerazione il passaggio a HashSet<T>
.
Secondo ciò che vedo usando .NET Reflector :
[Serializable, ComVisible(true)]
public abstract class DictionaryBase : IDictionary, ICollection, IEnumerable
{
// Fields
private Hashtable hashtable;
// Methods
protected DictionaryBase();
public void Clear();
.
.
.
}
Take note of these lines
// Fields
private Hashtable hashtable;
Quindi possiamo essere sicuri che DictionaryBase utilizzi internamente una HashTable.
Un oggetto Hashtable è composto da bucket che contengono gli elementi della raccolta. Un bucket è un sottogruppo virtuale di elementi all'interno di Hashtable, che rende la ricerca e il recupero più facili e veloci rispetto alla maggior parte delle raccolte .
La classe Dictionary ha la stessa funzionalità della classe Hashtable. Un dizionario di un tipo specifico (diverso da Object) ha prestazioni migliori rispetto a un Hashtable per i tipi di valore poiché gli elementi di Hashtable sono di tipo Object e, di conseguenza, il pugilato e l'unboxing si verificano in genere se si memorizza o si recupera un tipo di valore.
Per ulteriori informazioni: Hashtable e tipi di raccolta dei dizionari
Un'altra differenza che posso capire è:
Non possiamo usare il dizionario <KT, VT> (generici) con i servizi web. Il motivo è che nessuno standard di servizi Web supporta lo standard generico.
Collections
e Generics
sono utili per gestire gruppi di oggetti. In .NET, tutti gli oggetti delle raccolte si IEnumerable
nell'interfaccia IEnumerable
, che a sua volta ha ArrayList(Index-Value))
e HashTable(Key-Value)
. Dopo .NET framework 2.0, ArrayList
e HashTable
sono stati sostituiti con List
& Dictionary
. Ora, Arraylist
e HashTable
non sono più utilizzati nei progetti di oggi.
Venendo alla differenza tra HashTable
e Dictionary
, il Dictionary
è generico dove Hastable
non è generico. Possiamo aggiungere qualsiasi tipo di oggetto a HashTable
, ma durante il recupero dobbiamo lanciarlo al tipo richiesto. Quindi, non è sicuro. Ma per il dictionary
, pur dichiarandosi, possiamo specificare il tipo di chiave e valore, quindi non è necessario eseguire il cast durante il recupero.
Diamo un'occhiata a un esempio:
HashTable
class HashTableProgram
{
static void Main(string[] args)
{
Hashtable ht = new Hashtable();
ht.Add(1, "One");
ht.Add(2, "Two");
ht.Add(3, "Three");
foreach (DictionaryEntry de in ht)
{
int Key = (int)de.Key; //Casting
string value = de.Value.ToString(); //Casting
Console.WriteLine(Key + " " + value);
}
}
}
Dizionario,
class DictionaryProgram
{
static void Main(string[] args)
{
Dictionary<int, string> dt = new Dictionary<int, string>();
dt.Add(1, "One");
dt.Add(2, "Two");
dt.Add(3, "Three");
foreach (KeyValuePair<int, String> kv in dt)
{
Console.WriteLine(kv.Key + " " + kv.Value);
}
}
}
Dictionary<>
è un tipo generico e quindi è sicuro.
Puoi inserire qualsiasi tipo di valore in HashTable e questo a volte può generare un'eccezione. Ma Dictionary<int>
accetterà solo valori interi e allo stesso modo Dictionary<string>
accetterà solo stringhe.
Quindi, è meglio usare il Dictionary<>
invece di HashTable
.
Dictionary
<<< >>> differenze di Hashtable
:
- Generico <<< >>> Non generico
- Richiede la sincronizzazione del thread proprio <<< >>> Offre la versione thread-safe tramite il metodo
Synchronized()
- Elemento
KeyValuePair
:KeyValuePair
<<< >>> ElementoKeyValuePair
:DictionaryEntry
- Più recenti (> .NET 2.0 ) <<< >>> Più vecchi (da .NET 1.0 )
- è in System.Collections.Generic <<< >>> è in System.Collections
- Richiesta alla chiave non esistente genera un'eccezione <<< >>> Richiesta di chiavi non esistenti restituisce null
- potenzialmente un po ' più veloce per i tipi di valore <<< >>> più lento (necessita di boxing / unboxing) per i tipi di valore
Dictionary
/ similarità di Hashtable
:
- Entrambi sono internamente hashtables == accesso rapido ai dati di molti articoli in base alla chiave
- Entrambi hanno bisogno di chiavi immutabili e uniche
- Le chiavi di entrambi hanno bisogno del proprio metodo
GetHashCode()
Collezioni .NET simili (candidati da utilizzare al posto di Dictionary e Hashtable):
-
ConcurrentDictionary
- thread safe (accessibile in modo sicuro da più thread contemporaneamente) -
HybridDictionary
: prestazioni ottimizzate (per pochi articoli e anche per molti articoli) -
OrderedDictionary
: è possibile accedere ai valori tramite l'indice int (in base all'ordine in cui sono stati aggiunti gli articoli) -
SortedDictionary
: elementi ordinati automaticamente -
StringDictionary
: fortemente tipizzato e ottimizzato per le stringhe
Dizionario:
Restituisce / genera Eccezione se proviamo a trovare una chiave che non esiste.
È più veloce di un Hashtable perché non c'è boxe e unboxing.
Solo i membri statici pubblici sono thread-safe.
Il dizionario è un tipo generico che significa che possiamo usarlo con qualsiasi tipo di dati (durante la creazione, deve specificare i tipi di dati per entrambe le chiavi e valori).
Esempio:
Dictionary<string, string> <NameOfDictionaryVar> = new Dictionary<string, string>();
Dictionay è un'implementazione sicura per tipo di Hashtable,
Keys
eValues
sono fortemente tipizzati.
hashtable:
Restituisce null se proviamo a trovare una chiave che non esiste.
È più lento del dizionario perché richiede il pugilato e l'unboxing.
Tutti i membri di un Hashtable sono thread-safe,
Hashtable non è un tipo generico,
Hashtable è una struttura di dati con caratteri generici, possiamo aggiungere chiavi e valori di qualsiasi tipo.