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

当前回答

使用反射

关于此主题的Microsoft文档。

using System;
using System.Collections;
using System.Collections.Generic;

var anonObj = new { Id = 1, Name = "Foo" };
var anonType = anonObj.GetType();

var listType = typeof(List<>);

// We know that List<> have only one generic argument, so we do this:
var contructed = listType.MakeGenericType(anonType);

// Create instance
var instance = Activator.CreateInstance(contructed);

// Using it
var list = (IList)instance;
list.Add(anonObj);

对于Dictionary<,>,您需要传递2个参数 例:dicType。MakeGenericType(type1, type2)

对于带有约束的泛型类型(其中T: struct), 我们需要做更多的核实。查看微软文档来学习如何操作。

其他回答

您可以在代码中这样做。

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

这是一个老问题,但我想我会把我的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()。

魔力来自于元组的自定义扩展Add方法,如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...

}

我唯一不喜欢的是类型与名称分离,但如果您真的不想创建一个新类,那么这种方法仍然可以让您拥有可读的数据。

在最新版本4.0中,可以像下面这样使用动态

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

我通常使用以下方法;主要是因为你从一个空列表开始。

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

..这将为您提供已经添加了第一项的初始列表。

下面是另一种创建匿名类型列表的方法,它允许你从一个空列表开始,但仍然可以访问智能感知。

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

如果您想保留第一项,只需在字符串中放入一个字母。

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