Uma lista genérica de class anônima

No c # 3. 0 você pode criar uma class anônima com a seguinte syntax

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

Existe uma maneira de adicionar essas classs anônimas a uma lista genérica?

Exemplo:

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

Outro exemplo:

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

    Você poderia fazer:

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

    Há muitas maneiras de esfolar esse gato, mas basicamente elas usam inferência de tipos em algum lugar – o que significa que você precisa estar chamando um método genérico (possivelmente como um método de extensão). Outro exemplo pode ser:

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

    Você entendeu a ideia 🙂

    Aqui está a resposta.

     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); 

    Não exatamente, mas você pode dizer List e as coisas funcionarão. No entanto, list[0].Id não funcionará.

    Isso funcionará em tempo de execução no C # 4.0 com uma List , ou seja, você não obterá o IntelliSense.

    Há muitas maneiras de fazer isso, mas algumas das respostas aqui estão criando uma lista que contém elementos de lixo, o que requer que você limpe a lista.

    Se você estiver procurando por uma lista vazia do tipo genérico, use a opção Selecionar uma lista de tuplas para criar a lista vazia. Nenhum elemento será instanciado.

    Aqui está o one-liner para criar uma lista vazia:

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

    Então você pode adicioná-lo usando seu tipo genérico:

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

    Como alternativa, você pode fazer algo como abaixo para criar a lista vazia (Mas, eu prefiro o primeiro exemplo, porque você pode usá-lo para uma coleção populada de Tuples também):

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

    eu acho

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

    vai funcionar.

    Você também pode considerar escrever assim:

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

    Você pode fazer isso no seu código.

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

    Eu costumo usar o seguinte; principalmente porque você “inicia” com uma lista vazia.

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

    Ultimamente, eu tenho escrito assim:

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

    Usando o método de repetição também permitiria que você faça:

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

    ..que lhe dá a lista inicial com o primeiro item já adicionado.

    Aqui está a minha tentativa.

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

    Eu vim com isso quando escrevi algo semelhante para fazer uma lista anônima para um tipo personalizado.

    Eu verifiquei o IL em várias respostas. Este código fornece eficientemente uma lista vazia:

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

    Aqui está um outro método de criar uma lista de tipos anônimos que permite iniciar com uma lista vazia, mas ainda tem access ao IntelliSense.

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

    Se você quiser manter o primeiro item, basta colocar uma letra na string.

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

    Em vez disso:

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

    Você poderia fazer isso:

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

    No entanto, você receberá um erro de compiletime se tentar fazer algo assim em outro escopo, embora funcione em tempo de execução:

     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); } } 

    O problema é que apenas os membros do Object estão disponíveis em tempo de execução, embora o intellisense mostre o ID e o nome das propriedades.

    No .net 4.0, uma solução é usar a palavra-chave dynamic istead do object no código acima.

    Outra solução é usar a reflection para obter as propriedades

     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); 

    Na última versão 4.0, pode usar dinâmica como abaixo

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

    Esta é uma pergunta antiga, mas pensei em colocar minha resposta C # 6. Muitas vezes tenho que configurar dados de teste que são facilmente inseridos no código como uma lista de tuplas. Com algumas funções de extensão, é possível ter esse formato compacto e agradável, sem repetir os nomes em cada input.

     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 }); 

    Isto dá um IEnumerable – se você quiser uma lista que você pode adicionar a apenas adicionar ToList ().

    A mágica vem da extensão personalizada. Inclua methods para as tuplas, conforme descrito em 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... 

    }

    A única coisa que não gosto é que os tipos sejam separados dos nomes, mas se você realmente não quiser fazer uma nova class, essa abordagem ainda permitirá que você tenha dados legíveis.

    Para seu segundo exemplo, onde você deve inicializar uma nova List , uma idéia é criar uma lista anônima e, em seguida, desmarcá-la.

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

    Ou como um método de extensão, deve ser mais fácil:

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

    Ou provavelmente ainda mais curto,

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

    Você pode fazer assim:

     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" }); 

    Parece um pouco “hacky” para mim, mas funciona – se você realmente precisa ter uma lista e não pode simplesmente usar o array anônimo.

    Tente com isso:

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

    Você pode criar uma 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” é inicializado pelo primeiro valor adicionado.

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