3.5 匿名类型
匿名类型提供了一种方便的方法,可用来将一组只读属性封装到单个对象中,无需首先显式定义一个类型。类型名由编译器生成,并且不能在源代码级使用。每个属性的类型由编译器推断,可通过使用new运算符和对象初始值创建匿名类型。
3.5.1 理解匿名类型
匿名类型包括两种方式声明:一种是对象初始化器:另一种是隐式声明。下面用实际代码演示匿名类型的使用,代码如下。
这段代码说明了使用对象初始化器,初始化了一个匿名学生的类名输出学生的信息,输出结果如图3-16所示。
图3-16 匿名类型的使用
在以前版本的编译器中必须使用显示模式初始化对象和使用对象。现在新版的编译器使用对象初始化器,能够节省很多的代码。
3.5.2 匿名类型的内部呈现
匿名类型的继承是来自于System.Object基类,匿名类型不同于任何的引用类型,除了System.Object类型,它不能转换为其他类型,程序也不能直接访问它。
程序无法将字段、属性、时间或方法的返回类型声明为匿名类型,也不能将方法、属性构造函数或索引器正式声明为匿名类型。将匿名类型或包含匿名类型的集合作为参数传递给某一方法时,可将参数作为类型对象进行声明,但是这样做会使强类型化作用无效。如果必须存储查询结果或必须将查询结果传递到方法边界外部,则可以使用普通的命名结构。
由于匿名类型上的Equals和GetHashCode方法是根据方法属性的Equals和GetHashcode定义的,因此,仅当同一匿名类型两个实例的所有属性都相等时,这两个实例才相等。
下面通过代码演示匿名类型的具体类型。
从执行结果可以看到显示了具体的类型名称,如图3-17所示。
图3-17 匿名类型的信息
3.5.3 匿名类型的相等语法
匿名方法也可以通过对象比较来判断是否相同。如下代码显示了命名两个匿名对象,然后用不同方式比较类型是否相同。
比较结果如图3-18所示。这里可以看到对象比较完全相同,但值的比较不同,这说明了匿名对象的存储完全相同,但地址完全不同。
图3-18 比较结果
两个对象的内部结构如图3-19所示。
图3-19 内部结构比较
内部结构大部分都相同,细微差别在于对象的存储位置信息不同。