我理解,通常泛型是编译时安全的,并允许我们保持强类型集合。那么泛型如何允许我们存储匿名类型,如
List<object> TestList = new List<object>();
TestList.Add(new { id = 7, Name = "JonSkeet" });
TestList.Add(new { id = 11, Name = "Marc Gravell" });
TestList.Add(new { id = 31, Name = "Jason" });
答案 0 :(得分:9)
这是有效的,因为object
是.Net中所有实例的根类型。因此,任何表达都可以用于期望object
的位置,因为它们都符合System.object
的基本合同。
例如,以下内容完全合法。
List<object> TestList = new List<object>();
TestList.Add(new { id = 7, Name = "JonSkeet" });
TestList.Add("Foo");
TestList.Add(42);
答案 1 :(得分:7)
因为object
的所有内容都是(或可以装入),而List
是object
。
答案 2 :(得分:6)
其他人已经解释了为什么你的代码有效 - 你的例子是强类型的,因为一切都是一个对象,但这意味着它不是很有用。你不能从列表中获取元素并访问它们的Name
属性,因为它们只是对象,所以这通常不起作用。
但是,可以创建一个强类型的List
匿名类型 - 它只需要使用这样的小实用程序方法来完成:
static List<T> CreateList<T>(params T[] items) {
return items.ToList();
}
问题是你不能在没有提供类型名称的情况下调用构造函数。调用方法时,C#可以推断出类型参数,因此你可以这样写:
var testList = CreateList(
new { id = 7, Name = "JonSkeet" },
new { id = 11, Name = "Marc Gravell" });
testList.Add(new { id = 31, Name = "Jason" });
这是完全类型安全的,您可以编写testList[0].Name
来获取第一个人的姓名。如果您尝试编写类似testList.Add(42)
的内容,则会出现编译时错误,因为列表是强类型的,只包含具有id
和Name
属性的匿名类型。