2009-01-05 8 views
6

Puede inicializar una matriz de esta manera:Colección inicialización

int [ ] arr = { 1, 2, 3, 4, 5 }; 

pero List<T> no permite esto:

List<int> list = { 1, 2, 3, 4, 5 }; 

¿Cuál es la razón detrás de esto?

Después de todo ambos permiten esto:

int [ ] arr = new int [ ] { 1, 2, 3, 4, 5 }; 

List<int> list = new List<int> { 1, 2, 3, 4, 5 }; 

también por qué no es posible hacer esto con un LinkedList<T>:?

LinkedList<int> ll = new LinkedList<int>() { 1, 2, 3 }; 

actualización

Gracias chicos. Acabo de ver las respuestas. Quería elegir varias respuestas, pero no me lo permitió.

¿Por qué LinkedList tiene un método Agregar a través de una implementación explícita? ¿Esto probablemente será arreglado? Porque los problemas como este se convertirán en bolas de nieve cuando se pasen por alto, ¿no?

Respuesta

14

Su primera muestra es la sintaxis de lenguaje estándar para inicializar una matriz de enteros. El valor de la izquierda se evalúa como int []. En el segundo ejemplo, está intentando asignar un int [] a una lista <int>. El operador de asignación no admite esto ya que son tipos diferentes. Una lista <int> es no una matriz de tipo int. Como dices, sin embargo, hay un constructor para la Lista <int> que toma un int [] como argumento y el nuevo azúcar sintáctico agregado en C# 3.0 te permite la conveniencia de usar {} para agregar miembros a la colección definida por el constructor predeterminado

Como dice @Patrik, esto no funcionará para LinkedList porque no define el método Add() como parte de su interfaz (hay una implementación explícita de ICollection.Add) por lo que el azúcar sintáctico no trabajo.

Sin embargo, hay una solución fácil para LinkedList.

public class LinkedListWithInit<T> : LinkedList<T> 
{ 
    public void Add(T item) 
    { 
     ((ICollection<T>)this).Add(item); 
    } 
} 

LinkedList<int> list = new LinkedListWithInit<int> { 1, 2, 3, 4, 5 }; 
+0

Heh me ganó, pero en pocas palabras. +1 – Kev

+1

Creo que es un poco extraño, ya que LinkedList (T) acutally tiene un Add-method, implementado para la interfaz ICollection (T). Está implementado explícitamente, por lo que no es público a menos que lance la lista a una ICollection (T), pero creo que debería ser válida. –

+0

Pero no hay forma de convertirlo en ICollection entre crearlo intentando inicializarlo, por lo que la interfaz explícitamente implementada es inútil. He actualizado mi respuesta para aclarar esto. – tvanfosson

1

Nunca me di cuenta de que no puede usar la inicialización de colecciones con LinkedList (T), pero parece lógico ya que no tiene el método "Add", sino que tiene "AddFirst" y "AddLast". La inicialización de la colección usa el método "Agregar".

1

Porque la creación de matrices está integrada en el lenguaje, por ejemplo int [], float [], WhateverClassHere []. Esta sintaxis es para hacer arreglos, no para inicializar listas.

En su ejemplo, está haciendo una serie de entradas. Usar esa sintaxis para agregar valores a una lista no debería funcionar porque List no es una matriz.

+0

Puede instanciar matrices de tipos complejos como este, no tiene nada que ver con eso. La pregunta es por qué la sintaxis para crear una matriz difiere de la inicialización de la colección. –

+0

Oh, no me di cuenta de eso. –

6

Aquí es lo que el C# 3.0 Lengua Spec tiene que decir sobre el tema:

El siguiente es un ejemplo de una expresión de creación objeto que incluye un inicializador de colección:

List<int> digits = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 

El objeto de la colección a la que una colección se aplica el inicializador debe ser de un tipo que implementa System.Collections.IEnumerable o se produce un error de tiempo de compilación . Para cada elemento especificado en orden, el colección inicializador invoca una método Add en el objeto de destino con la lista expresión del elemento inicializador como lista de argumentos, aplicando resolución de sobrecarga normal para cada invocación. Por lo tanto, el objeto de recopilación debe contener un método Add aplicable para cada inicializador de elementos.

Eso tiene sentido cuando lo piensas. El compilador se asegura de que está trabajando en un tipo enumerable que implementa una función Agregar (a través de la cual realiza la inicialización).

Cuestiones relacionadas