En C # 3.0 puede crear una clase anónima con la siguiente sintaxis
var o = new { Id = 1, Name = "Foo" };
¿Hay alguna manera de agregar estas clases anónimas a una lista genérica?
Ejemplo:
var o = new { Id = 1, Name = "Foo" };
var o1 = new { Id = 2, Name = "Bar" };
List<var> list = new List<var>();
list.Add(o);
list.Add(o1);
Otro ejemplo:
List<var> list = new List<var>();
while (....)
{
....
list.Add(new {Id = x, Name = y});
....
}
c#
.net
generics
anonymous-types
DHornpout
fuente
fuente
new[] { new{ Id = (int?)null, Name = "Foo" }, new { Id = (int?)1, Name = "Foo" }}
Respuestas:
Podrías hacerlo:
Hay muchas formas de desollar a este gato, pero básicamente usarán inferencia de tipos en alguna parte, lo que significa que debe llamar a un método genérico (posiblemente como un método de extensión). Otro ejemplo podría ser:
Tienes la idea :)
fuente
Aquí está la respuesta.
fuente
string.Join
interpolación de métodos y cadenas, por lo que no es necesario usarforeach
yFormat
.Hay muchas formas de hacer esto, pero algunas de las respuestas aquí están creando una lista que contiene elementos basura, lo que requiere que borre la lista.
Si está buscando una lista vacía del tipo genérico, use Seleccionar contra una Lista de tuplas para hacer la lista vacía. No se instanciarán elementos.
Aquí está la línea para crear una lista vacía:
Luego puede agregarle usando su tipo genérico:
Como alternativa, puede hacer algo como a continuación para crear la lista vacía (pero, prefiero el primer ejemplo porque también puede usarlo para una colección poblada de tuplas):
fuente
Enumerable.Empty<object>().Select(o=>definition).ToList()
No exactamente, pero puedes decir
List<object>
y las cosas funcionarán. Sin embargo,list[0].Id
no funcionará.Esto funcionará en tiempo de ejecución en C # 4.0 al tener un
List<dynamic>
, es decir, no obtendrá IntelliSense.fuente
supongo
trabajará.
También podría considerar escribirlo así:
fuente
Usualmente uso lo siguiente; principalmente porque luego "comienzas" con una lista que está vacía.
Últimamente, lo he estado escribiendo así:
Usar el método de repetición también le permitiría hacer:
..que le da la lista inicial con el primer elemento ya agregado.
fuente
Puedes hacer esto en tu código.
fuente
En la última versión 4.0, puede usar dinámicas como a continuación
fuente
Revisé el IL en varias respuestas. Este código proporciona eficientemente una lista vacía:
fuente
IEnumerable
, mientras que mi versión regresaList
, exactamente lo que OP ha pedido.new object[] { }.Select(o => new { Id = default(int), Name = default(string) }).ToList()
Aquí está mi intento.
Se me ocurrió esto cuando escribí algo similar para hacer una Lista anónima para un tipo personalizado.
fuente
Puede crear una lista de dinámica.
"dinámico" se inicializa con el primer valor agregado.
fuente
En lugar de esto:
Podrías hacer esto:
Sin embargo, obtendrá un error en tiempo de compilación si intenta hacer algo como esto en otro ámbito, aunque funciona en tiempo de ejecución:
El problema es que solo los miembros de Object están disponibles en tiempo de ejecución, aunque intellisense mostrará el ID y el nombre de las propiedades .
En .net 4.0 una solución es usar la palabra clave dinámica en lugar de objeto en el código anterior.
Otra solución es usar la reflexión para obtener las propiedades.
fuente
Aquí hay otro método para crear una Lista de tipos anónimos que le permite comenzar con una lista vacía, pero aún así tener acceso a IntelliSense.
Si desea conservar el primer elemento, simplemente ponga una letra en la cadena.
fuente
fuente
Esta es una vieja pregunta, pero pensé en poner mi respuesta C # 6. A menudo tengo que configurar datos de prueba que se ingresan fácilmente en el código como una lista de tuplas. Con un par de funciones de extensión, es posible tener este formato agradable y compacto, sin repetir los nombres en cada entrada.
Esto proporciona un IEnumerable: si desea una lista a la que pueda agregar, simplemente agregue ToList ().
La magia proviene de la extensión personalizada Agregar métodos para tuplas, como se describe en https://stackoverflow.com/a/27455822/4536527 .
}
Lo único que no me gusta es que los tipos están separados de los nombres, pero si realmente no desea crear una nueva clase, este enfoque aún le permitirá tener datos legibles.
fuente
Estoy muy sorprendido de que nadie haya sugerido inicializadores de colección. De esta manera solo se pueden agregar objetos cuando se crea la lista, de ahí el nombre, sin embargo, parece ser la mejor manera de hacerlo. No es necesario crear una matriz y luego convertirla en una lista.
Siempre se puede usar en
object
lugar dedynamic
intentar mantenerlo de una manera genérica, perodynamic
tiene más sentido.fuente
Puedes hacerlo de esta manera:
Me parece un poco "hacky", pero funciona, si realmente necesita tener una lista y no puede usar la matriz anónima.
fuente
Para su segundo ejemplo, donde debe inicializar una nueva
List<T>
, una idea es crear una lista anónima y luego borrarla.O como método de extensión, debería ser más fácil:
O probablemente incluso más corto,
fuente
Si usa C # 7 o superior, puede usar tipos de tupla en lugar de tipos anónimos.
fuente
Derivando de esta respuesta , se me ocurrieron dos métodos que podrían hacer la tarea:
Puedes usar los métodos como
Esta respuesta tiene una idea similar, pero no la vi hasta que hice esos métodos.
fuente
Prueba con esto:
fuente
fuente