Tutorial :A generic list of anonymous class



Question:

In C# 3.0 you can create anonymous class with the following syntax

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

Is there a way to add these anonymous class to a generic list?

Example:

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

Another Example:

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


Solution:1

You could do:

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

There are lots of ways of skinning this cat, but basically they'll all use type inference somewhere - which means you've got to be calling a generic method (possibly as an extension method). Another example might be:

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

You get the idea :)


Solution:2

Here is the answer.

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


Solution:3

Not exactly, but you can say List<object> and things will work. However, list[0].Id won't work.

This will work at runtime in C# 4.0 by having a List<dynamic>, that is you won't get IntelliSense.


Solution:4

There are many ways to do this, but some of the responses here are creating a list that contains garbage elements, which requires you to clear the list.

If you are looking for an empty list of the generic type, use a Select against a List of Tuples to make the empty list. No elements will be instantiated.

Here's the one-liner to create an empty list:

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

Then you can add to it using your generic type:

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

As an alternative, you can do something like below to create the empty list (But, I prefer the first example because you can use it for a populated collection of Tuples as well) :

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


Solution:5

I guess

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

will work.

You might also consider writing it like this:

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


Solution:6

You can do this in your code.

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


Solution:7

I usually use the following; mainly because you then "start" with a list that's empty.

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

Lately, I've been writing it like this instead:

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

Using the repeat method would also allow you to do:

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

..which gives you the initial list with the first item already added.


Solution:8

Here is my attempt.

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

I came up with this when I wrote something similar for making a Anonymous List for a custom type.


Solution:9

I checked the IL on several answers. This code efficiently provides an empty List:

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


Solution:10

Here is a another method of creating a List of anonymous types that allows you to start with an empty list, but still have access to IntelliSense.

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

If you wanted to keep the first item, just put one letter in the string.

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


Solution:11

Instead of this:

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

You could do this:

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

However, you will get a compiletime error if you try to do something like this in another scope, although it works at runtime:

private List<object> GetList()  {       List<object> list = new List<object>();      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);       }  }  

The problem is that only the members of Object are available at runtime, although intellisense will show the properties id and name.

In .net 4.0 a solution is to use the keyword dynamic istead of object in the code above.

Another solution is to use reflection to get the properties

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<T> GetList<T>(params T[] elements)          {              var a = TypeGenerator(elements);              return a;          }            public static List<T> TypeGenerator<T>(T[] at)          {              return new List<T>(at);          }            private void WriteList<T>(List<T> 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();          }      }  }  


Solution:12

var list = new[]{  new{  FirstField = default(string),  SecondField = default(int),  ThirdField = default(double)  }  }.ToList();  list.RemoveAt(0);  


Solution:13

This is an old question, but I thought I'd put in my C# 6 answer. I often have to set up test data that is easily entered in-code as a list of tuples. With a couple of extension functions, it is possible to have this nice, compact format, without repeating the names on each entry.

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

This gives an IEnumerable - if you want a list that you can add to then just add ToList().

The magic comes from custom extension Add methods for tuples, as described at https://stackoverflow.com/a/27455822/4536527.

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

}

The only thing I don't like is that the types are separated from the names, but if you really don't want to make a new class then this approach will still let you have readable data.


Solution:14

For your second example, where you have to initialize a new List<T>, one idea is to create an anonymous list, and then clear it.

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

Or as an extension method, should be easier:

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

Or probably even shorter,

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


Solution:15

In latest version 4.0, can use dynamic like below

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


Solution:16

You can do it this way:

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

It seems a little "hacky" to me, but it works - if you really need to have a list and can't just use the anonymous array.


Solution:17

Try with this:

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


Solution:18

You can create a list of dynamic.

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

"dynamic" gets initialized by the first value added.


Solution:19

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

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »