Archive

Posts Tagged ‘Tópicos Avançados’

Inicializadores de coleções

maio 26, 2010 2 comentários

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.

Categorias:.NET Tags:,