C# - Usando um Dicionário para armazenar e obter itens


 Neste artigo veremos como usar a classe Dictionary para armazenar e retornar itens usando a linguagem C#.

A classe Dictionary representa uma coleção de chaves e valores. É uma coleção do tipo chave/valor e implementa  a interface IDictionary que possui duas coleções no seu interior uma para guardar a chave e outra para guardar o valor.

Esta classe esta definida no namespace System.Collections.Generic sendo uma classe genérica e pode armazenar qualquer tipo de dados em uma forma de chaves e valor, onde cada chave deve ser exclusiva na coleção.

A classe Dictionary fornece recursos semelhantes a uma Hashtable, mas é fortemente tipada. Isso significa que seu código não precisa converter de objetos genéricos em tipos específicos. Isso também significa que a classe Dictionary garante que seu código passe os tipos corretos de objetos para ele.

O objeto Dictionary pode ser atribuído a uma variável do tipo IDictionary<Tkey,TValue> ou à classe Dictionary <TKey,Tvalue>. Exemplo de inicialização:

IDictionary<int, string> dict = new Dictionary<int, string>();
        
Dictionary<int, string> dict = new Dictionary<int, string>();

No código cima especificamos os tipos de chave e valor ao declarar um objeto de dicionário.

Um int é um tipo de chave e string é um tipo de valor que será armazenado em um objeto de dicionário chamado dict. Você pode usar qualquer tipo de dados C# válido para chaves e valores.

As principais propridades da classe Dictionary são:

Propriedade Descrição
 Count Obtém o número total de elementos no Dictionary<TKey,TValue>.
 IsReadOnly Retorna um booleano indicando se o Dictionary<TKey,TValue> é somente leitura.
 Item Obtém ou define o elemento com a chave especificada no Dictionary<TKey,TValue>.
 Keys Retorna a coleção de chaves do Dictionary<TKey,TValue>
 Values Retorna a coleta de valores no Dictionary<TKey,TValue>.

Os principais métodos da classe Dictionary são:

Método Descrição
Add Adiciona um item à coleção Dictionary.
Add Adiciona pares de valores-chave na coleção Dictionary<TKey,TValue>.
Remove Remove a primeira ocorrência do item especificado do Dictionary<TKey,TValue>.
Remove Remove o elemento com a chave especificada.
ContainsKey Verifica se a chave especificada existe em Dictionary<TKey,TValue>.
ContainsValue Verifica se o valor especificado existe em Dictionary<TKey,TValue>.
Clear Remove todos os elementos do Dictionary<TKey,TValue>.
TryGetValue Retorna true e atribui o valor com a chave especificada, se a chave não existir, retorna false.

A seguir veremos algumas operações mostrando como usar a classe Dictionary.

Criando o projeto Console

Vamos criar um vou criar um projeto Console usando o template Console App(.NET Framework)  usando o VS 2017 Community com o nome CShp_Dictionary;

1- Adicionando elementos a um Dictionary

Use o método Add() para adicionar um par chave-valor ao dicionário. Add(Tkey,TValue)   

            IDictionary<int, string> dic1= new Dictionary<int, string>();
            dic1.Add(1, "Maria");
            dic1.Add(2, "Paulo");
            dic1.Add(3, "Pedro");

Podemos inicializar um Dicionario usando a sintaxe do inicializador de coleções com chaves e valores, conforme mostrado abaixo.

            IDictionary<int, string> dic2 = new Dictionary<int, string>()
            {
                               {1,"Maria"},
                               {2, "Paulo"},
                               {3,"Pedro"}
            };

2- Acessando elementos de um Dictionary

Os elementos do dicionário podem ser acessados de muitas maneiras quer usando um laço foreach ou um indexador.

Usamos um foreach ou loop para iterar sobre todos os elementos do dicionário. O dicionário armazena pares de valores-chave. Assim, você pode usar um tipo KeyValuePair<TKey,TValue> ou uma variável implicitamente tipada  no laço foreach, conforme mostrado abaixo.

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
             Dictionary<int, string> dic1 = new Dictionary<int, string>()
             {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
              };
            foreach (KeyValuePair<int, string> item in dic1)
            {
                Console.WriteLine("chave: {0}, valor: {1}", item.Key, item.Value);
            }
        }
    }
}

Se for usar um laço for pode usar a propridade Count para obter o número total de elementos do dicionário:

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> dic1 = new Dictionary<int, string>()
            {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
            };           
           for (int i = 0; i < dic1.Count; i++)
	{
		Console.WriteLine("chave: {0}, valor: {1}",dic1.Keys.ElementAt(i), 
					dic1[dic1.Keys.ElementAt(i)]);
	}
	Console.ReadKey();
        }
    }
}

Podemos também usar o dicionario como um array para acessar seus elementos individuais. Para isso basta especificar a chave (não o índice) para obter um valor de um dicionário usando o indexador como um array.   

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> dic1 = new Dictionary<int, string>()
            {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
            };
            Console.WriteLine(dic1[2]);   // retorna laranja
            Console.WriteLine(dic1[4]);   // retorna abacate 
            Console.ReadKey();
        }
    }
}

Se você não tiver certeza sobre a chave, use o método TryGetValue() que vair retornar false se não puder encontrar chaves em vez de gerar uma exceção.

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> dic1 = new Dictionary<int, string>()
            {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
            };
            string resultado;
            if (dic1.TryGetValue(4, out resultado))
            {
                Console.WriteLine(resultado);
            }
            else
            {
                Console.WriteLine("Não foi possível achar a chave especificada.");
            }
        }
    }
}

3 - Verificar se há elementos existentes

Um Dicionário contém vários métodos para determinar se um ele contém elementos ou chaves especificados. Use o método ContainsKey() para verificar se uma chave especificada existe no dicionário ou não.

Use o método Contains() para verificar se um par de chave e valor especificado existe no dicionário ou não.

Assinaturas:

Exemplo:

using System;
using System.Collections.Generic;
using System.Linq;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> dic1 = new Dictionary<int, string>()
            {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
            };
            Console.WriteLine(dic1.ContainsKey(1)); // retorna true
	 Console.WriteLine(dic1.ContainsKey(6)); // retorna false

	 // retorna true
	 Console.WriteLine(dic1.Contains(new KeyValuePair<int, string>(3, "Manga"))); 
	 Console.ReadKey();
            Console.ReadKey();
        }
    }
}
 

4 - Remover elementos de um dicionário

Use o método Remove() para remover um item existente do dicionário. Este método possui duas sobrecargas:

  1. Um método aceita uma chave -  bool Remove(Tkey key)
  2. Outro método aceita um KeyValuePair<> como um parâmetro - bool Remove(KeyValuePair<TKey,TValue>)

Exemplo:

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            Dictionary<int, string> dic1 = new Dictionary<int, string>()
            {
                                                {1,"Banana"},
                                                {2, "Laranja"},
                                                {3, "Manga"},
                                                {4, "Abacate"},
                                                {5,"Maça"}
            };
            // remove o item com chave igual a 1
            dic1.Remove(1); 
            Console.ReadKey();
        }
    }
}   

4 - Ordenando um dicionario

Para ordenar um dicionário use a coleção genérica SortedDictionary que ordena o dicionário com base nas chaves.

Exemplo:

using System;
using System.Collections.Generic;
namespace CShp_Dictionary
{
    class Program
    {
        static void Main(string[] args)
        {
            //criando um dicionario ordenado
            SortedDictionary<string, int> dic2 = new SortedDictionary<string, int>();
            // Adicionando strings e chaves do tipo int
            dic2.Add("zebra", 5);
            dic2.Add("cachorro", 2);
            dic2.Add("gato", 9);
            dic2.Add("pardal", 4);
            dic2.Add("C#", 100);
            // Verifica se gato existe no dicionario
            if (dic2.ContainsKey("gato"))
            {
                Console.WriteLine("tem um gato ai...");
            }
            // Verifica se tem zebra 
            if (dic2.ContainsKey("zebra"))
            {
                Console.WriteLine("Deu zebra pois não tem zebra ai...");
            }
            // Verifica se contém C#
            // e se tiver pega o valor
            int v;
            if (dic2.TryGetValue("C#", out v))
            {
                Console.WriteLine(v);
            }
            // Imprime o SortedDictionary em ordem alfabética
            foreach (KeyValuePair<string, int> p in dic2)
            {
                Console.WriteLine("{0} = {1}", p.Key, p.Value);
            }
            Console.ReadKey();
        }
    }
}

E estamos conversados...

Pegue o código do projeto aqui :  CShp_Dictionary.zip

"Dando graças ao Pai que nos fez idôneos para participar da herança dos santos na luz;
O qual nos tirou da potestade das trevas, e nos transportou para o reino do Filho do seu amor;
Em quem temos a redenção pelo seu sangue, a saber, a remissão dos pecados;
O qual é imagem do Deus invisível, o primogênito de toda a criação;"
Colossenses 1:12-15

Referências:


José Carlos Macoratti