更新: 2008 年 7 月

匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,而无需首先显式定义一个类型。类型名由编译器生成,并且不能在源代码级使用。这些属性的类型由编译器推断。下面的示例演示一个用两个分别名为 Amount 和 Message 的属性初始化的匿名类型。

 复制代码
var v = new { Amount = 108, Message = "Hello" };

匿名类型通常用在查询表达式的 select 子句中,以便返回源序列中每个对象的属性子集。有关查询的更多信息,请参见 LINQ 查询表达式(C# 编程指南)

匿名类型是使用 new 运算符和对象初始值设定项创建的。有关对象初始值设定项的更多信息,请参见对象和集合初始值设定项(C# 编程指南)

匿名类型是由一个或多个公共只读属性组成的类型。不允许包含其他种类的类成员(如方法或事件)。匿名类型不能强制转换为除 object 以外的任何接口或类型。

最常见的方案是用其他类型的一些属性初始化匿名类型。在下面的示例中,假定一个名为 Product 的类包含 ColorPrice 属性以及其他几个您不感兴趣的属性。Products 是一个 Product 对象集合。匿名类型声明以 new 关键字开始。它初始化了一个只使用 Product 的两个属性的新类型。这将导致在查询中返回较少数量的数据。

如果您没有在匿名类型中指定成员名称,编译器会为匿名类型成员指定与用于初始化这些成员的属性相同的名称。必须为使用表达式初始化的属性提供名称。

C# 复制代码
var productQuery = 
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

在将匿名类型分配给变量时,必须使用 var 构造初始化该变量。这是因为只有编译器能够访问匿名类型的基础名称。有关 var 的更多信息,请参见隐式类型的局部变量(C# 编程指南)

备注

匿名类型是直接从对象派生的引用类型。尽管应用程序无法访问匿名类型,但编译器仍会为其提供一个名称。从公共语言运行时的角度来看,匿名类型与任何其他引用类型没有什么不同,唯一区别在于匿名类型无法强制转换为除 object 以外的任何类型。

如果两个或更多个匿名类型以相同的顺序具有相同数量和种类的属性,则编译器会将这些匿名类型视为相同的类型,并且它们共享编译器生成的相同类型信息。

匿名类型具有方法范围。若要向方法边界外部传递一个匿名类型或一个包含匿名类型的集合,必须首先将匿名类型强制转换为对象。但是,这会使匿名类型的强类型化无效。如果必须存储查询结果或者必须将查询结果传递到方法边界外部,请考虑使用普通的命名结构或类而不是匿名类型。

匿名类型不能像属性一样包含不安全类型。

由于匿名类型上的 EqualsGetHashCode 方法是根据属性的 EqualsGetHashcode 定义的,因此仅当同一匿名类型的两个实例的所有属性都相等时,这两个实例才相等。

请参见

修订记录

日期

修订记录

原因

2008 年 7 月

在介绍性文字和“备注”部分增加了关于强制转换限制的信息。

信息补充。