泛型和匿名类型

时间:2010-04-01 15:19:00

标签: c# generics

我理解,通常泛型是编译时安全的,并允许我们保持强类型集合。那么泛型如何允许我们存储匿名类型,如

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

3 个答案:

答案 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的所有内容都是(或可以装入),而Listobject

答案 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)的内容,则会出现编译时错误,因为列表是强类型的,只包含具有idName属性的匿名类型。