在C#3.0中,您可以使用以下语法创建匿名类
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});
....
}
#1楼
static void Main()
{
List<int> list = new List<int>();
list.Add(2);
list.Add(3);
list.Add(5);
list.Add(7);
}
#2楼
您可以在代码中执行此操作。
var list = new[] { new { Id = 1, Name = "Foo" } }.ToList();
list.Add(new { Id = 2, Name = "Bar" });
#3楼
这是答案。
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);
#4楼
对于第二个示例,必须初始化一个新的List<T>
,一个想法是创建一个匿名列表,然后将其清除。
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();
#5楼
我通常使用以下内容; 主要是因为您随后从一个空列表开始。
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"} );
使用repeat方法还可以使您执行以下操作:
var myObj = new { ID = 1, Name = "John" };
var list = Enumerable.Repeat(myObj, 1).ToList();
list.Add(new { ID = 2, Name = "Liana" });
..这将为您提供初始列表以及已添加的第一项。
#6楼
试试这个:
var result = new List<object>();
foreach (var test in model.ToList()) {
result.Add(new {Id = test.IdSoc,Nom = test.Nom});
}
#7楼
这是创建匿名类型列表的另一种方法,该方法使您可以从一个空列表开始,但仍可以访问IntelliSense。
var items = "".Select( t => new {Id = 1, Name = "foo"} ).ToList();
如果要保留第一项,只需在字符串中输入一个字母即可。
var items = "1".Select( t => new {Id = 1, Name = "foo"} ).ToList();
#8楼
有很多方法可以做到这一点,但是这里的一些响应正在创建一个包含垃圾元素的列表,这需要您清除列表。
如果要查找泛型类型的空列表,请使用针对元组列表的选择来创建空列表。 没有元素将被实例化。
这是创建一个空列表的单行代码:
var emptyList = new List<Tuple<int, string>>()
.Select(t => new { Id = t.Item1, Name = t.Item2 }).ToList();
然后,您可以使用通用类型将其添加到其中:
emptyList.Add(new { Id = 1, Name = "foo" });
emptyList.Add(new { Id = 2, Name = "bar" });
或者,您可以执行以下操作来创建空列表(但是,我更喜欢第一个示例,因为您也可以将其用于填充的元组集合):
var emptyList = new List<object>()
.Select(t => new { Id = default(int), Name = default(string) }).ToList();
#9楼
我检查了几个答案的IL。 此代码有效地提供了一个空列表:
using System.Linq;
…
var list = new[]{new{Id = default(int), Name = default(string)}}.Skip(1).ToList();
#10楼
这是一个老问题,但是我想我应该填写C#6答案。 我经常必须设置易于在代码中以元组列表形式输入的测试数据。 有了几个扩展功能,就可以拥有这种精巧紧凑的格式,而无需在每个条目上重复名称。
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...
}
我唯一不喜欢的是类型与名称分开,但是如果您真的不想创建一个新类,那么这种方法仍然可以让您拥有可读的数据。
#11楼
代替这个:
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);
但是,如果您尝试在另一个作用域中执行类似的操作,则会遇到编译时错误,尽管它可以在运行时运行:
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);
}
}
问题是,尽管intellisense将显示属性id和name ,但只有Object的成员在运行时可用。
在.net 4.0中,一种解决方案是在上面的代码中使用关键字dynamic代替object 。
另一种解决方案是使用反射来获取属性
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();
}
}
}
#12楼
在最新版本4.0中,可以使用如下所示的动态
var list = new List<dynamic>();
list.Add(new {
Name = "Damith"
});
foreach(var item in list){
Console.WriteLine(item.Name);
}
}
#13楼
您可以创建一个动态列表。
List<dynamic> anons=new List<dynamic>();
foreach (Model model in models)
{
var anon= new
{
Id = model.Id,
Name=model.Name
};
anons.Add(anon);
}
“动态”通过添加的第一个值进行初始化。
#14楼
从这个答案得出 ,我想出了两种可以完成任务的方法:
/// <summary>
/// Create a list of the given anonymous class. <paramref name="definition"/> isn't called, it is only used
/// for the needed type inference. This overload is for when you don't have an instance of the anon class
/// and don't want to make one to make the list.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="definition"></param>
/// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
public static List<T> CreateListOfAnonType<T>(Func<T> definition)
#pragma warning restore RECS0154 // Parameter is never used
{
return new List<T>();
}
/// <summary>
/// Create a list of the given anonymous class. <paramref name="definition"/> isn't added to the list, it is
/// only used for the needed type inference. This overload is for when you do have an instance of the anon
/// class and don't want the compiler to waste time making a temp class to define the type.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="definition"></param>
/// <returns></returns>
#pragma warning disable RECS0154 // Parameter is never used
public static List<T> CreateListOfAnonType<T>(T definition)
#pragma warning restore RECS0154 // Parameter is never used
{
return new List<T>();
}
您可以使用类似的方法
var emptyList = CreateListOfAnonType(()=>new { Id = default(int), Name = default(string) });
//or
var existingAnonInstance = new { Id = 59, Name = "Joe" };
var otherEmptyList = CreateListOfAnonType(existingAnonInstance);
这个答案有一个相似的想法,但是直到做出这些方法后我才看到它。
#15楼
我很惊讶没有人建议使用集合初始值设定项。 这种方法只能在创建列表时添加对象,因此要添加名称,但是这似乎是执行此操作的最佳方法。 无需创建数组,然后将其转换为列表。
var list = new List<dynamic>()
{
new { Id = 1, Name = "Foo" },
new { Id = 2, Name = "Bar" }
};
您始终可以使用object
而不是dynamic
object
,但是尝试以一种真正的通用方式保留object
,那么dynamic
更有意义。
#16楼
如果您使用的是C#7或更高版本,则可以使用元组类型代替匿名类型。
var myList = new List<(int IntProp, string StrProp)>();
myList.Add((IntProp: 123, StrProp: "XYZ"));
#17楼
不完全是,但是您可以说List<object>
,一切都会正常。 但是, list[0].Id
将不起作用。
通过使用List<dynamic>
,这将在C#4.0 中的运行时工作,即不会获得IntelliSense。
#18楼
您可以这样做:
var list = new[] { o, o1 }.ToList();
剥皮这只猫的方法有很多,但是基本上它们都会在某个地方使用类型推断-这意味着您必须调用通用方法(可能是扩展方法)。 另一个示例可能是:
public static List<T> CreateList<T>(params T[] elements)
{
return new List<T>(elements);
}
var list = CreateList(o, o1);
你明白了:)
#19楼
我猜
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 });
}
#20楼
您可以这样操作:
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" });
对我来说似乎有点“ hacky”,但它确实有效-如果您确实需要一个列表并且不能只使用匿名数组。
#21楼
这是我的尝试。
List<object> list = new List<object> { new { Id = 10, Name = "Testing1" }, new {Id =2, Name ="Testing2" }};
当我写了类似的文章为自定义类型创建匿名列表时,我想到了这一点。
#22楼
var list = new[]{
new{
FirstField = default(string),
SecondField = default(int),
ThirdField = default(double)
}
}.ToList();
list.RemoveAt(0);