Início > .NET > Inicializadores de coleções

Inicializadores de coleções

Ontem, o Leonardo, estagiário da equipe na qual trabalho, fez uma pergunta muito interessante a respeito da inicialização da classe Dictionary<TKey, TValue>. Na verdade, ele fez uma constatação, não uma pergunta. Ele me mostrou um bloco semelhante ao seguinte código

Dictionary<string, string> propriedades = new Dictionary<string, string>()
{
 { "Nome", "Carlos Loth" },
 { "Idade", "26 anos" }
}

E comentou que, inicialmente, estava tentando inicializar uma instância da class Dictionary utilizando novas instâncias da estrutura KeyValuePair<TKey, TValue> e esta abordagem não estava funcionando. Mudando um pouco o exemplo inicial, o código que ele tinha escrito inicialmente era mais ou menos assim

Dictionary<string, string> propriedades = new Dictionary<string, string>()
{
  new KeyValuePair<string, string>("Nome", "Carlos Loth"),
  new KeyValuePair<string, string>("Idade", "26 anos")
}

Contudo, quanto tentava compilar este código, acontecia um erro: a classe Dictionary<TKey, TValue> não possui uma sobrecarga do método Add que receba apenas um argumento.

Eu fiquei intrigado com isto, pois a princípio eu achei que o código da primeira listagem nem fosse compilar. Mas, de fato, ele está correto. A especificação da linguagem C# 4.0, diz, na seção 7.6.10.3 Collection Initializers, que uma expressão de inicialização de coleções chama o método Add no objeto de destino para cada um dos elementos da de inicialização na ordem que foram especificados. Além disto, a lista na expressão de inicialização de cada elemento é passada como argumento do método Add. Sendo assim, o objeto coleção deve possuir um método Add aplicável para cada inicializador de elemento para que o uso desta sintaxe seja possível.

Portanto, como a classe Dictionary tem apenas um método Add(TKey key, TValue value) é por isto que a primeira lista de código é válida e a segunda não. Além disto, a especificação também mostra um exemplo do código que a expressão de inicialização de coleções gera, que adaptando ao meu exemplo seria

Dictionary<string, string> __cdict = new Dictionary<String, String>();
__cdict.Add("Nome", "Carlos Loth");
__clist.Add("Idade", "26 anos");
Dictionary<string, string> propriedades = __cdict;

Onde __cdict é uma variável intermediária que não é visível nem acessível ao programador do código que utiliza a sintaxe de inicialização.

Eu utilizo bastante a sintaxe de inicialização para objetos e arrays, mas confesso que nunca tinha utilizado para coleções mais sofisticadas como a classe Dictionary. Agora aprendi os detalhes de como ela funciona para coleções.

Leonardo, muito obrigado por compartilhar esta dica e instigar a discussão na nossa equipe.

Anúncios
Categorias:.NET Tags:,
  1. Leonardo Nowaczyk
    maio 31, 2010 às 12:39

    isso que é legal do .net, sempre se descobre jeitos novos e “mais sofisticados” de fazer as coisas deixando o codigo mais claro.
    valeu pelos créditos.. hehe..

  2. maio 31, 2010 às 12:54

    @Leonardo: Obrigado por compartilhar esta dica, assim a gente vai aprendendo cada vez mais um com o outro. Uma lição que fica a respeito deste tópico em especial, é que a melhor fonte de informação sobre como a linguagem C# funciona internamente é o documento de especificação da linguagem C# 4.0. A partir de agora, sempre que eu tiver alguma dúvida vou consultar primeiro a especificação.

  1. No trackbacks yet.

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s

%d blogueiros gostam disto: