匿名类的通用列表
在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); }