> 文章列表 > 23.04.05 《CLR via C#》 笔记3
23.04.05 《CLR via C#》 笔记3
网友:sslake
文章列表
2024-03-21 17:53:33

第四章 类型基础
- 所有类型隐式继承System.Object
- public方法:Equals;GetHashCode(如果类型需要作为键使用,需要重写该方法);ToString;GetType
- protected方法:MemberwiseClone;Finalize
- 所有对象都用new操作符创建
- 计算类型和所有基类型字段成员的字节数,以及对象的额外成员(类型对象指针、同步块索引)
- 从堆中分配需要的字节数(内存),置为0
- 初始化对象的类型对象指针、同步块索引
- 调用类型的构造器(构造器中调用基类构造器)
- 没有delete操作符显式释放对象
- 类型转换(由于GetType不是虚函数,一个类型无法伪装成另一个类型)
- 对象可以转换成它的任何基类型
- is操作符,返回true或false,不抛出异常(对象引用null返回false)
- as操作符,不抛出异常(不能转型返回null)
- 命名空间和程序集
- using指令自动为类型尝试附加命名空间前缀(简化打字),实际CLR只知道类的完整的名称,不知道“命名空间”
- 消除歧义(两个命名空间中有相同类型的名字)
- 使用别名 using xxx = xxx.xxx
- 使用完整公司的名称来作为顶级命名空间名称
- 命名空间和程序集不一定相关,同一命名空间的类型可能在不同程序集中实现
- 类型、对象、线程栈在运行时的相互关系
- 调用方法时,实参和返回地址压栈
- 方法开始执行时,分配局部变量压栈
- return时,局部变量、返回地址、实参依次出栈,返回原状态
- CLR中的情况
- 确认方法中的所有引用类型,确保相应程序集都已加载
- 创建数据结构表示类型本身(类型对象指针、同步块索引、静态字段、静态方法)
- 线程栈开始执行代码,在栈中分配局部变量的内存
- 遇到new操作符的情况
- 在堆上创建对象,初始化类型对象指针来引用该类型对象
- 初始化同步块索引,将实例字段置为0或null
- 返回内存地址
- 调用静态方法
- CLR找到定义了该静态方法的类型对象
- JIT对方法进行编译
- 调用JIT编译好的代码
- 调用非虚方法
- JIT找到调用者类型的类型对象
- 若对象没有该虚方法,不断回溯类层次结构(直到Object类)
- 找到被调用方法的记录项后,编译、执行
- 调用虚方法
- JIT生成一段额外代码,先执行额外代码:
- 找到调用者类型的类型对象,检查其类型对象指针
- 根据指针找到实际类型
- 在类型对象的方法表中找到该方法
- 若发现实际类型不匹配,将在内部实例化新的对象,从新的类型对象方法表中找到该方法
- 编译、执行方法
- 类型对象的本质
- CLR开始运行时,会为System.Type创建类型对象
- 类型对象也是对象,在创建时必须初始化类型对象指针,初始化成对Type类型对象的引用
- Type类的类型对象也是对象,它的类型对象指针指向自己
- GetType方法返回的就是类的类型对象的类型对象指针