Para responder à pergunta, primeiro precisamos dar uma olhada no propósito de um dicionário e da tecnologia subjacente.
Dictionary
é a lista de KeyValuePair<Tkey, Tvalue>
onde cada valor é representado por sua chave exclusiva. Digamos que temos uma lista de suas comidas favoritas. Cada valor (nome do alimento) é representado por sua chave exclusiva (a posição = o quanto você gosta desse alimento).
Código de exemplo:
Dictionary<int, string> myDietFavorites = new Dictionary<int, string>()
{
{ 1, "Burger"},
{ 2, "Fries"},
{ 3, "Donuts"}
};
Digamos que você queira se manter saudável, mudou de ideia e deseja substituir seu "hambúrguer" favorito por salada. Sua lista ainda é uma lista de seus favoritos, você não mudará a natureza da lista. Seu favorito permanecerá em primeiro lugar na lista, apenas seu valor será alterado. É quando você chama isso de:
/*your key stays 1, you only replace the value assigned to this key
you alter existing record in your dictionary*/
myDietFavorites[1] = "Salad";
Mas não se esqueça que você é o programador, e a partir de agora você termina suas frases com; você se recusa a usar emojis porque eles gerariam um erro de compilação e toda a lista de favoritos é baseada em 0 índice.
Sua dieta também mudou! Então, você altera sua lista novamente:
/*you don't want to replace Salad, you want to add this new fancy 0
position to your list. It wasn't there before so you can either define it*/
myDietFavorites[0] = "Pizza";
/*or Add it*/
myDietFavorites.Add(0, "Pizza");
Existem duas possibilidades com a definição: você deseja fornecer uma nova definição para algo que não existia antes ou deseja alterar a definição que já existe.
O método Adicionar permite adicionar um registro, mas apenas sob uma condição: a chave para esta definição pode não existir no seu dicionário.
Agora vamos dar uma olhada sob o capô. Quando você está fazendo um dicionário, seu compilador faz uma reserva para o intervalo (espaços na memória para armazenar seus registros). Bucket não armazena chaves da maneira como você as define. Cada chave é hash antes de ir para o balde (definido pela Microsoft), vale a pena mencionar que a parte do valor permanece inalterada.
Usarei o algoritmo de hash CRC32 para simplificar meu exemplo. Quando você define:
myDietFavorites[0] = "Pizza";
O que vai para o balde é db2dc565 "Pizza" (simplificado).
Quando você altera o valor com:
myDietFavorites[0] = "Spaghetti";
Você hash seu 0, que é novamente db2dc565, e então procura esse valor em seu depósito para descobrir se ele está lá. Se estiver lá, você simplesmente reescreve o valor atribuído à chave. Se não estiver lá, você colocará seu valor no balde.
Ao chamar a função Adicionar em seu dicionário, como:
myDietFavorite.Add(0, "Chocolate");
Você hash seu 0 para comparar seu valor com os do intervalo. Você pode colocá-lo no balde somente se ele não estiver lá .
É crucial saber como funciona, especialmente se você trabalha com dicionários de string ou tipo de chave char. É sensível a maiúsculas e minúsculas devido ao hashing em curso. Por exemplo, "nome"! = "Nome". Vamos usar nosso CRC32 para representar isso.
O valor para "nome" é: e04112b1 O
valor para "Nome" é: 1107fb5b