第 4 章 类型基础
第 4 章 类型基础
NyxX第 4 章 类型基础
本章内容:
4.1 所有类型都从 System.Object 派生
表 4-1 System.Object 的公共方法
| 公共方法 | 说明 |
|---|---|
Equals |
如果两个对象具有相同的值,就返回 true。欲知该方法的详情,请参见 5.3.2 节“对象相等性和同一性” |
GetHashCode |
返回对象的值的哈希码。如果某个类型的对象要在哈希表集合(比如 Dictionary)中作为建使用,类型应重写该方法。 |
ToString |
默认返回类型的完整名称(this.GetType().FullName)。但经常重写该方法来返回包含对象状态表示的 String 对象。 |
GetType |
返回从 Type 派生的一个类型的实例,指出调用 GetType 的那个对象是什么类型。返回的 Type 对象可以和反射类配合,获取与对象的类型有关的元数据信息。 GetType 是非虚方法,目的是防止类重写该方法,隐瞒其类型,进而破坏类型安全性 |
new 操作符所做的事情。
- 计算类型及其所有基类型(一直到
System.Object,虽然它没有定义自己的实例字段)中定义的所有实例字段需要的字节数。堆上每个对象都需要一些额外的成员,包括 “类型对象指针” 和 “同步块索引” 。CLR 利用这些成员管理对象。 - 从托管堆中分配类型要求的字节数,从而分配对象的内存,分配的所有字节都设为零.
- 初始化对象的“类型对象指针”和“同步块索引”成员。
- 调用类型的实例构造器,传递在
new调用中指定的实参。大多数编译器都在构造器中自动生成代码来调用基类构造器。每个类型的构造器都负责初始化该类型定义的实例字段。最终调用System.Object的构造器,该构造器什么都不做,简单地返回。
new 执行了所有这些操作之后,返回指向新建对象一个引用。
4.2 类型转换
类型安全是 CLR 极其重要的一个特点。
在运行时,CLR 检查转型操作,确定总是转换为对象的实际类型或者它的任何基类型。
使用 C# 的 is 和 as 操作符来转型
is 检查对象是否兼容于指定类型,返回 Boolean 值 true 或 false。 is 操作符永远不抛出异常as 操作符 CLR 只校验一次对象类型,只是它永远不抛出异常——相反,如果对象不能转型,结果就是null。
4.3 命名空间和程序集
命名空间和程序集的关系
命名空间和程序集(实现类型的文件)不一定相关。特别是,同一个命名空间中的类型可能在不同程序集中实现。
同一个程序集也可能包含不同命名空间中的类型。
4.4 运行时的相互关系
定义类型时,可在类型内部定义静态数据字段。为这些静态数据字段提供支援的字节在类型对象自身中分配。每个类型对象最后都包含一个方法表。在方法表中,类型定义的每个方法都有对应的记录项。
每个类型对象都有一个字段引用了它的基类型,如果类型没有定义在调用的那个方法,JIT 编译器会回溯类层次结构(一直回溯到 Object),并在沿途的每个类型中查找该方法。
调用虚实例方法时,JIT 编译器要在方法中生成一些额外的代码;方法每次调用都会执行这些代码。这些代码首先检查发出调用的变量,并跟随地址来到发出调用的对象。然后,代码检查对象内部的“类型对象指针”成员,该成员指向对象的实际类型。然后,代码在类型对象的方法表中查找引用了被调用方法的记录项,对方法进行 JIT 编译(如果需要的话),再调用 JIT 编译好的代码。





