Tipos de coleção Hashtable e Dictionary
A classe System.Collections.Hashtable, e as classes genéricas System.Collections.Generic.Dictionary<TKey,TValue> e System.Collections.Concurrent.ConcurrentDictionary<TKey,TValue>, implementam a interface System.Collections.IDictionary. A classe genérica Dictionary<TKey,TValue> também implementa a interface genérica IDictionary<TKey,TValue>. Portanto, cada elemento nessas coleções é um par chave-valor.
Um Hashtable objeto consiste em buckets que contêm os elementos da coleção. Um bucket é um subgrupo virtual de elementos dentro de Hashtable, o que torna a pesquisa e a recuperação mais fáceis e rápidas do que na maioria das coleções. Cada bucket é associado um código hash, que é gerado usando uma função de hash e tem como base a chave do elemento.
A classe HashSet<T> genérica é uma coleção não ordenada com a finalidade de conter elementos exclusivos.
Uma função de hash é um algoritmo que retorna um código hash numérico com base em uma chave. A chave é o valor da alguma propriedade do objeto sendo armazenado. Uma função de hash deve sempre retornar o mesmo código hash para a mesma chave. É possível para uma função de hash gerar o mesmo código hash para duas chaves diferentes, mas uma função de hash que gera um código hash exclusivo para cada chave específica resulta em um melhor desempenho ao recuperar os elementos da tabela de hash.
Cada objeto que é usado como um elemento em um Hashtable deve ser capaz de gerar um código hash para si mesmo usando uma implementação do método GetHashCode. No entanto, você também pode especificar uma função de hash para todos os elementos em uma Hashtable usando um construtor Hashtable que aceita uma implementação IHashCodeProvider como um de seus parâmetros.
Quando um objeto é adicionado a um Hashtable, ele é armazenado no compartimento de memória que está associado ao código hash que corresponde ao código hash do objeto. Quando um valor está sendo procurado no Hashtable, o código hash é gerado para esse valor e o bucket associado a esse código hash é pesquisado.
Por exemplo, uma função de hash para uma cadeia de caracteres pode pegar os códigos ASCII de cada caractere na cadeia e adicioná-los em conjunto para gerar um código hash. A cadeia de caracteres "piquenique" teria um código hash diferente daquele da cadeia de caracteres "cesta"; portanto, as cadeias de caracteres "piquenique" e "cesta" ficariam em buckets diferentes. Por outro lado, "stressed" e "desserts" teriam o mesmo código hash e ficariam no mesmo bucket.
As classes Dictionary<TKey,TValue> e ConcurrentDictionary<TKey,TValue> têm a mesma funcionalidade que a classe Hashtable. Um Dictionary<TKey,TValue> de um tipo específico (diferente de Object) fornece desempenho melhor do que um Hashtable para tipos de valor. Isso ocorre porque os elementos de Hashtable são do tipo Object; portanto, conversões boxing e unboxing normalmente ocorrem quando você armazena ou recupera um tipo de valor. A classe ConcurrentDictionary<TKey,TValue> deve ser usada quando vários threads podem estar acessando a coleção simultaneamente.