TOC

This article has been localized into Portuguese by the community.

Coleções:

Dicionários

Dicionários em C# implementam a interface IDictionary. Existem vários tipos de Dicionário, mas o mais comumente usado é o Dicionário genérico, geralmente chamado de Dictionary<TKey, TValue> - contém uma chave específica do tipo e um valor específico do tipo correspondente. Isso é basicamente o que separa um dicionário de uma lista - os itens de uma lista vêm em uma ordem específica e podem ser acessados por um índice numérico, onde os itens em um dicionário são armazenados com uma chave exclusiva, que pode ser usada para recuperar item novamente.

Vamos nos aprofundar mais no que são os dicionários, mas primeiro, vamos dar uma olhada em um exemplo simples, para mostrar a você tudo o que é:

Dictionary<string, int> users = new Dictionary<string, int>();  
users.Add("John Doe", 42);  
users.Add("Jane Doe", 38);  
users.Add("Joe Doe", 12);  
users.Add("Jenna Doe", 12);

Console.WriteLine("John Doe is " + users["John Doe"] + " years old");

Conheça a família Doe, que mais uma vez são os dados de teste para um exemplo neste tutorial. Papai, mamãe e os gêmeos Joe e Jenna. Observe como eu defino o dicionário para usar uma string como a chave (nesse caso, o nome) e um inteiro para o valor (nesse caso, uma idade). O legal é que isso nos permite acessar um item do dicionário usando a chave (nome), em vez de um índice numérico. Você pode ver que em ação na última linha do exemplo - entre um conjunto de colchetes, simplesmente especificamos a chave, para acessar o valor (a idade).

Há duas coisas importantes para saber aqui: Primeiro de tudo, a chave tem que ser única. Nesse caso, onde usamos uma string como chave, isso significa que você não pode adicionar dois usuários com o mesmo nome. Isso faz muito sentido, porque quando você pode usar a chave para fazer referência a um único item, a chave só pode apontar para um valor. Por outro lado, isso torna este exemplo um pouco simples demais, porque obviamente você não pode ter uma coleção de usuários onde nomes duplicados não possam existir, mas tenha paciência comigo por enquanto.

A outra coisa que você terá que lembrar, ao acessar valores de um dicionário, é que a chave precisa existir na coleção, quando você tenta acessar seu valor. Em outras palavras, o meu exemplo só foi seguro porque eu estava no controle total do que a lista continha - na maioria das situações, você deve sempre verificar se a chave existe, antes de tentar usá-la - assim:

string key = "John Doe";
if(users.ContainsKey(key))
    Console.WriteLine("John Doe is " + users[key] + " years old");

Se você tentar adicionar uma chave que já existe ou se tentar acessar um valor com uma chave que não existe , o .NET lançará uma exceção. Isso pode parecer óbvio, mas ambos são muito comumente encontrados nos logs de exceção em todo o mundo.

Trabalhando com os itens

Acessar um único item pode ser muito útil, mas e se você quiser percorrer a coleção e, por exemplo, procurar algo? Nesse caso, a primeira coisa que você deve saber é que os itens na lista obviamente não são apenas um objeto simples - em vez disso, o Dicionário contém itens do tipo KeyValuePair<TKey, TValue>. Os T's são os tipos que você usou para declarar a lista - neste caso, uma string e um inteiro. Então, percorrer a coleção com um loop foreach seria algo assim:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users)
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

A primeira coisa que você pode notar é que usei a oportunidade para alterar a maneira como inicializamos o dicionário - em vez de adicionar manualmente cada item após instanciar o dicionário, usamos a sintaxe do inicializador de coleção, conforme descrito em um artigo anterior.

Com isso fora do caminho, agora temos o mesmo dicionário de antes - vamos percorrê-lo. Como você pode ver, eu uso um loop foreach e declarei o tipo de item que espero como um KeyValuePair & lt; string, int & gt; - exatamente os mesmos dois tipos usados para declarar o dicionário. Agora podemos acessar tanto a chave quanto o valor (nome e idade) de cada item, e usamos isso para gerar uma cadeia simples de informações sobre a pessoa no Console.

A ordem dos itens

O exemplo acima nos leva a um ponto muito importante: ao contrário de uma List, onde a ordem básica dos itens é determinada por índices numéricos, a ordem dos itens em um dicionário é não-determinística - você simplesmente não pode confiar nos itens que estão em uma determinada ordem, nem mesmo quando você adiciona manualmente cada item individualmente. Claro, quando você executar o exemplo acima, provavelmente perceberá que os itens estão exatamente na mesma ordem em que os adicionamos, mas não é garantido e, assim que você tiver um dicionário com mais itens e começar a adicionar e remover itens, a ordem provavelmente será alterada.

A classe Dictionary não vem com um método Sort(), porque no final, mesmo se você classificá-lo, o pedido pode mudar assim que você começar a trabalhar com ele novamente. Em vez disso, você pode usar os métodos OrderBy() e OrderByDescending() do LINQ (mais sobre isso em outro capítulo) para obter uma cópia ordenada do Dicionário. Isso também permite que você classifique pela chave ou pelo valor, o que pode ser útil em nosso exemplo, para que os usuários saiam na ordem da idade:

Dictionary<string, int> users = new Dictionary<string, int>()
{
    { "John Doe", 42 },
    { "Jane Doe", 38 },
    { "Joe Doe", 12 },
    { "Jenna Doe", 12 }
};
foreach (KeyValuePair<string, int> user in users.OrderBy(user => user.Value))
{
    Console.WriteLine(user.Key + " is " + user.Value + " years old");
}

Se você executar o exemplo, verá que, embora o dicionário seja declarado com os itens em um único pedido, podemos obtê-los facilmente em outro pedido, conforme acharmos adequado. Apenas lembre-se de que você é responsável por garantir que você obtenha os itens na ordem que deseja, porque o .NET framework armazena-os exatamente como achar melhor.


This article has been fully translated into the following languages: Is your preferred language not on the list? Click here to help us translate this article into your language!