匿名类的通用列表

在C#3.0中,您可以使用以下语法创build匿名类

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

有没有办法将这些匿名类添加到通用列表?

例:

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

另一个例子:

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

你可以这样做:

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

这个猫有很多方法,但基本上他们都会在某个地方使用types推断 – 这意味着你必须调用一个通用的方法(可能是一个扩展方法)。 另一个例子可能是:

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

你明白了:)

这是答案。

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

不完全是这样,但是你可以说List<object> ,事情就会起作用。 但是, list[0].Id将不起作用。

这将在C#4.0 运行时有一个List<dynamic> ,这是你不会得到IntelliSense。

有很多方法可以做到这一点,但是这里的一些响应是创build一个包含垃圾元素的列表,这要求您清除列表。

如果您正在查找genericstypes的空列表,请使用对元组列表进行select来创build空列表。 没有元素将被实例化。

以下是创build一个空列表的单行程序:

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

那么你可以使用你的genericstypes来添加它:

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

作为一种select,你可以做下面的事情来创build空的列表(但是,我更喜欢第一个例子,因为你也可以使用它来填充tuples的集合):

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

我猜

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

将工作。

你也可以考虑这样写:

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

你可以在你的代码中做到这一点。

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

我通常使用以下; 主要是因为你然后“开始”一个空的列表。

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

最近,我一直这样写:

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

使用重复方法也可以让你做到:

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

..给你的第一个项目已经添加的初始列表。

这是我的尝试。

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

当我编写类似的自定义types的匿名列表时,我想到了这个。

这是创build匿名types列表的另一种方法,它允许您从空列表开始,但仍然可以访问IntelliSense。

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

如果你想保留第一个项目,只需要在string中放一个字母。

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

我在几个答案中检查了IL。 此代码有效地提供了一个空的列表:

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

而不是这个:

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

你可以这样做:

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

但是,如果您尝试在另一个作用域中执行类似操作,则会遇到编译时错误,尽pipe它在运行时可以正常工作:

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

问题是只有Object的成员在运行时才可用,但intellisense将显示属性id名称

在.net 4.0中,解决scheme是在上面的代码中使用关键字dynamic istead 对象

另一个解决scheme是使用reflection来获取属性

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

这是一个古老的问题,但我想我会把我的C#6的答案。 我经常需要设置testing数据,这些数据很容易作为元组列表input到代码中。 有了几个扩展function,就可以拥有这个不错的紧凑格式,而不用重复每个条目的名称。

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

这给了一个IEnumerable – 如果你想要一个列表,你可以添加到然后只是添加ToList()。

魔法来自自定义扩展为元组添加方法,如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... 

}

我唯一不喜欢的是types是从名称中分离出来的,但是如果你真的不想创build一个新的类,那么这个方法仍然会让你有可读的数据。

对于你的第二个例子,你必须初始化一个新的List<T> ,一个想法是创build一个匿名列表,然后清除它。

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

或作为扩展方法,应该更容易:

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

或者可能更短,

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

你可以这样做:

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

对我来说,这看起来有点“黑客”,但它起作用 – 如果你真的需要有一个列表,不能只使用匿名数组。

在最新的4.0版本中,可以使用如下的dynamic

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

试试这个:

 var result = new List<object>(); foreach (var test in model.ToList()) { result.Add(new {Id = test.IdSoc,Nom = test.Nom}); } 
 static void Main() { List<int> list = new List<int>(); list.Add(2); list.Add(3); list.Add(5); list.Add(7); }