泛型和匿名类型

use*_*364 2 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" });
Run Code Online (Sandbox Code Playgroud)

Jar*_*Par 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);
Run Code Online (Sandbox Code Playgroud)


Ada*_*ght 7

因为一切都是(或者可以盒装成)一个object,这是一个Listobject秒.


Tom*_*cek 6

其他人已经解释了为什么你的代码有效 - 你的例子是强类型的,因为一切都是一个对象,但这意味着它不是很有用.你不能从列表中获取元素并访问例如它们的Name属性,因为它们只是对象,所以这通常不起作用.

但是,可以创建一个强类型List的匿名类型 - 它只需要使用这样的小实用程序方法完成:

static List<T> CreateList<T>(params T[] items) {
  return items.ToList();
}
Run Code Online (Sandbox Code Playgroud)

问题是,如果不提供类型名称,则无法调用构造函数.调用方法时,C#可以推断出类型参数,所以你可以这样写:

var testList = CreateList(
  new { id = 7, Name = "JonSkeet" },
  new { id = 11, Name = "Marc Gravell" });
testList.Add(new { id = 31, Name = "Jason" });
Run Code Online (Sandbox Code Playgroud)

这是完全类型安全的,你可以写例如testList[0].Name获取第一个人的名字.如果您尝试写的东西一样testList.Add(42),你会得到一个编译时错误,因为列表是强类型只包含匿名类型的idName性质.