Hoje fiquei surpreso ao descobrir que em C # eu posso fazer:
List<int> a = new List<int> { 1, 2, 3 };
Por que eu posso fazer isso? Qual construtor é chamado? Como posso fazer isso com minhas próprias aulas? Eu sei que essa é a maneira de inicializar matrizes, mas matrizes são itens de idioma e Listas são objetos simples ...
c#
.net
list
initialization
Ignacio Soler Garcia
fonte
fonte
{ { "key1", "value1"}, { "key2", "value2"} }
List<int>
é na verdade apenas uma matriz. Eu odeio a equipe de C # pelo fato de não nomearem issoArrayList<T>
que soa tão óbvio e natural.Respostas:
Isso faz parte da sintaxe do inicializador de coleção no .NET. Você pode usar esta sintaxe em qualquer coleção criada, desde que:
Implementa
IEnumerable
(preferencialmenteIEnumerable<T>
)Tem um método chamado
Add(...)
O que acontece é que o construtor padrão é chamado e, em seguida,
Add(...)
é chamado para cada membro do inicializador.Assim, esses dois blocos são aproximadamente idênticos:
E
Você pode chamar um construtor alternativo, se desejar, por exemplo, para evitar sobredimensionar o tamanho
List<T>
durante o crescimento, etc:Observe que o
Add()
método não precisa levar um único item; por exemplo, oAdd()
métodoDictionary<TKey, TValue>
leva dois itens:É aproximadamente idêntico a:
Portanto, para adicionar isso à sua própria classe, tudo o que você precisa fazer, como mencionado, é implementar
IEnumerable
(novamente, de preferênciaIEnumerable<T>
) e criar um ou maisAdd()
métodos:Então você pode usá-lo como as coleções BCL:
(Para mais informações, consulte o MSDN )
fonte
List<int> temp = new List<int>(); temp.Add(1); ... List<int> a = temp;
que é, aa
variável não é inicializado até depois de toda a adiciona são chamados. Caso contrário, seria legal fazer algo como oList<int> a = new List<int>() { a.Count, a.Count, a.Count };
que é uma coisa louca de se fazer.List<int> a; a = new List<int>() { a.Count };
eList<int> a = new List<int>() { a.Count };
T x = y;
é a mesma queT x; x = y;
, Esse fato pode levar a algumas situações estranhas. Por exemplo,int x = M(out x) + x;
é perfeitamente legal porqueint x; x = M(out x) + x;
é legal.IEnumerable<T>
; o não genéricoIEnumerable
é suficiente para permitir o uso da sintaxe do inicializador de coleção.using (var x = new Something{ 1, 2 })
não descartará o objeto se uma dasAdd
chamadas falhar.É o chamado açúcar sintático .
List<T>
é a classe "simples", mas o compilador oferece um tratamento especial para facilitar sua vida.Esse é o chamado inicializador de coleção . Você precisa implementar
IEnumerable<T>
eAdd
método.fonte
De acordo com a especificação do C # versão 3.0 "O objeto de coleção ao qual um inicializador de coleção é aplicado deve ser de um tipo que implemente System.Collections.Generic.ICollection por exatamente um T."
No entanto, essas informações parecem imprecisas até o momento da redação deste documento; veja o esclarecimento de Eric Lippert nos comentários abaixo.
fonte
Ele funciona graças aos inicializadores de coleção que basicamente exigem que a coleção implemente um método Add e que fará o trabalho por você.
fonte
Outra coisa interessante sobre os inicializadores de coleção é que você pode ter várias sobrecargas de
Add
método e chamá-las todas no mesmo inicializador! Por exemplo, isso funciona:Chama as sobrecargas corretas. Além disso, procura apenas o método com nome
Add
, o tipo de retorno pode ser qualquer coisa.fonte
A matriz como sintaxe está sendo transformada em uma série de
Add()
chamadas.Para ver isso em um exemplo muito mais interessante, considere o código a seguir, no qual eu faço duas coisas interessantes que parecem ilegais em C #, 1) configurando uma propriedade somente leitura, 2) configurando uma lista com uma matriz como inicializador.
Esse código funcionará perfeitamente, embora 1) MyList seja somente leitura e 2) eu defina uma lista com o inicializador de array.
A razão pela qual isso funciona é porque, no código que faz parte de um inicializador de objetos, o compilador sempre transforma qualquer
{}
sintaxe semelhante em uma série deAdd()
chamadas que são perfeitamente legais, mesmo em um campo somente leitura.fonte