Una lista genérica de clase anónima

En C # 3.0 puedes crear clases anónimas con la siguiente syntax

var o = new { Id = 1, Name = "Foo" }; 

¿Hay alguna forma 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 list = new List(); list.Add(o); list.Add(o1); 

Otro ejemplo:

 List list = new List(); while (....) { .... list.Add(new {Id = x, Name = y}); .... } 

Podrías hacerlo:

 var list = new[] { o, o1 }.ToList(); 

Hay muchas maneras de despellejar a este gato, pero básicamente todos usarán inferencia de tipo en alguna parte, lo que significa que debes llamar a un método genérico (posiblemente como método de extensión). Otro ejemplo podría ser:

 public static List CreateList(params T[] elements) { return new List(elements); } var list = CreateList(o, o1); 

Entiendes la idea 🙂

Aquí está la respuesta.

 string result = String.Empty; var list = new[] { new { Number = 10, Name = "Smith" }, new { Number = 10, Name = "John" } }.ToList(); foreach (var item in list) { result += String.Format("Name={0}, Number={1}\n", item.Name, item.Number); } MessageBox.Show(result); 

No exactamente, pero puede decir List y las cosas funcionarán. Sin embargo, la list[0].Id no funcionará.

Esto funcionará en tiempo de ejecución en C # 4.0 al tener una List , es decir, no obtendrá IntelliSense.

Hay muchas maneras de hacerlo, pero algunas de las respuestas aquí son la creación de una lista que contiene elementos de elementos no utilizados, lo que requiere que borre la lista.

Si está buscando una lista vacía del tipo genérico, use un Seleccionar contra una Lista de Tuplas para hacer la lista vacía. No se crearán instancias de elementos.

Aquí está el delineador para crear una lista vacía:

  var emptyList = new List>() .Select(t => new { Id = t.Item1, Name = t.Item2 }).ToList(); 

Luego puede agregarlo usando su tipo genérico:

  emptyList.Add(new { Id = 1, Name = "foo" }); emptyList.Add(new { Id = 2, Name = "bar" }); 

Como alternativa, puede hacer algo como lo siguiente para crear la lista vacía (Pero, prefiero el primer ejemplo porque también puede usarlo para una colección poblada de Tuples):

  var emptyList = new List() .Select(t => new { Id = default(int), Name = default(string) }).ToList(); 

supongo

 List CreateEmptyGenericList(T example) { return new List(); } void something() { var o = new { Id = 1, Name = "foo" }; var emptyListOfAnonymousType = CreateEmptyGenericList(o); } 

trabajará.

También podría considerar escribirlo así:

 void something() { var String = string.Emtpy; var Integer = int.MinValue; var emptyListOfAnonymousType = CreateEmptyGenericList(new { Id = Integer, Name = String }); } 

Puedes hacer esto en tu código.

 var list = new[] { new { Id = 1, Name = "Foo" } }.ToList(); list.Add(new { Id = 2, Name = "Bar" }); 

Usualmente uso lo siguiente; principalmente porque luego “comienzas” con una lista que está vacía.

 var list = Enumerable.Range(0, 0).Select(e => new { ID = 1, Name = ""}).ToList(); list.Add(new {ID = 753159, Name = "Lamont Cranston"} ); //etc. 

Últimamente, lo he estado escribiendo así:

 var list = Enumerable.Repeat(new { ID = 1, Name = "" }, 0).ToList(); list.Add(new {ID = 753159, Name = "Lamont Cranston"} ); 

Usar el método de repetición también te permitirá hacer:

 var myObj = new { ID = 1, Name = "John" }; var list = Enumerable.Repeat(myObj, 1).ToList(); list.Add(new { ID = 2, Name = "Liana" }); 

..que te da la lista inicial con el primer elemento ya agregado.

Aquí está mi bash.

 List list = new List { new { Id = 10, Name = "Testing1" }, new {Id =2, Name ="Testing2" }}; 

Se me ocurrió esto cuando escribí algo similar para hacer una lista anónima para un tipo personalizado.

Revisé el IL en varias respuestas. Este código proporciona de manera eficiente una lista vacía:

  using System.Linq; … var list = new[]{new{Id = default(int), Name = default(string)}}.Skip(1).ToList(); 

Aquí hay otro método para crear una Lista de tipos anónimos que le permite comenzar con una lista vacía, pero que aún tiene acceso a IntelliSense.

 var items = "".Select( t => new {Id = 1, Name = "foo"} ).ToList(); 

Si quería conservar el primer artículo, simplemente coloque una letra en la cadena.

 var items = "1".Select( t => new {Id = 1, Name = "foo"} ).ToList(); 

En lugar de esto:

 var o = new { Id = 1, Name = "Foo" }; var o1 = new { Id = 2, Name = "Bar" }; List  list = new List(); list.Add(o); list.Add(o1); 

Podrías hacer esto:

 var o = new { Id = 1, Name = "Foo" }; var o1 = new { Id = 2, Name = "Bar" }; List list = new List(); list.Add(o); list.Add(o1); 

Sin embargo, obtendrá un error de comstackción si intenta hacer algo como esto en otro ámbito, aunque funciona en tiempo de ejecución:

 private List GetList() { List list = new List(); var o = new { Id = 1, Name = "Foo" }; var o1 = new { Id = 2, Name = "Bar" }; list.Add(o); list.Add(o1); return list; } private void WriteList() { foreach (var item in GetList()) { Console.WriteLine("Name={0}{1}", item.Name, Environment.NewLine); } } 

El problema es que solo los miembros de Object están disponibles en tiempo de ejecución, aunque intellisense mostrará las propiedades id y name .

En .NET 4.0, una solución es usar la palabra clave dynamic en lugar de objeto en el código anterior.

Otra solución es usar la reflexión para obtener las propiedades

 using System; using System.Collections.Generic; using System.Reflection; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Program p = new Program(); var anonymous = p.GetList(new[]{ new { Id = 1, Name = "Foo" }, new { Id = 2, Name = "Bar" } }); p.WriteList(anonymous); } private List GetList(params T[] elements) { var a = TypeGenerator(elements); return a; } public static List TypeGenerator(T[] at) { return new List(at); } private void WriteList(List elements) { PropertyInfo[] pi = typeof(T).GetProperties(); foreach (var el in elements) { foreach (var p in pi) { Console.WriteLine("{0}", p.GetValue(el, null)); } } Console.ReadLine(); } } } 
 var list = new[]{ new{ FirstField = default(string), SecondField = default(int), ThirdField = default(double) } }.ToList(); list.RemoveAt(0); 

En la última versión 4.0, puede usar dinámica como a continuación

 var list = new List(); list.Add(new { Name = "Damith" }); foreach(var item in list){ Console.WriteLine(item.Name); } } 

Esta es una vieja pregunta, pero pensé que pondría mi respuesta C # 6. A menudo tengo que configurar los 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.

 var people= new List>() { {1, 11, "Adam"}, {2, 22, "Bill"}, {3, 33, "Carol"} }.Select(t => new { Id = t.Item1, Age = t.Item2, Name = t.Item3 }); 

Esto le da un IEnumerable: si desea una lista a la que pueda agregarle, 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 .

 public static class TupleListExtensions { public static void Add(this IList> list, T1 item1, T2 item2) { list.Add(Tuple.Create(item1, item2)); } public static void Add(this IList> list, T1 item1, T2 item2, T3 item3) { list.Add(Tuple.Create(item1, item2, item3)); } // and so on... 

}

Lo único que no me gusta es que los tipos estén separados de los nombres, pero si realmente no quieres hacer una nueva clase, este enfoque te permitirá tener datos legibles.

Para su segundo ejemplo, donde tiene que inicializar una nueva List , una idea es crear una lista anónima y luego borrarla.

 var list = new[] { o, o1 }.ToList(); list.Clear(); //and you can keep adding. while (....) { .... list.Add(new { Id = x, Name = y }); .... } 

O como un método de extensión, debería ser más fácil:

 public static List GetEmptyListOfThisType(this T item) { return new List(); } //so you can call: var list = new { Id = 0, Name = "" }.GetEmptyListOfThisType(); 

O probablemente aún más corto,

 var list = new int[0].Select(x => new { Id = 0, Name = "" }).Tolist(); 

Puedes hacerlo de esta manera:

 var o = new { Id = 1, Name = "Foo" }; var o1 = new { Id = 2, Name = "Bar" }; var array = new[] { o, o1 }; var list = array.ToList(); list.Add(new { Id = 3, Name = "Yeah" }); 

Me parece un poco “hacky”, pero funciona, si realmente necesitas tener una lista y no puedes simplemente usar la matriz anónima.

Prueba con esto:

 var result = new List(); foreach (var test in model.ToList()) { result.Add(new {Id = test.IdSoc,Nom = test.Nom}); } 

Puede crear una lista de dinámica.

 List anons=new List(); foreach (Model model in models) { var anon= new { Id = model.Id, Name=model.Name }; anons.Add(anon); } 

“dynamic” se inicializa con el primer valor agregado.

 static void Main() { List list = new List(); list.Add(2); list.Add(3); list.Add(5); list.Add(7); }