为什么C#中通过System.Object的GetType函数可以拿到当前实例的类型
本文摘自《CLR via C# 第4版》的中文译本92-97页。该书由Jeffrey Richter编写。该书下载链接见如下小编的资源链:
https://download.csdn.net/download/tanjiaqi2554/10504069
要解答以上的问题,首先你得知道,对于C#的CLR来说,所有类型其实就是“实例”,CLR为所有的类型对象在托管堆上分配了以下几个东西:
1.类型对象指针
2.同步块索引
3.类中的静态字段
4.类中包含所有方法的方法表(由JIT实时编译对应的方法代码)
而当我们实例化类型时,则在托管堆上分配了以下东西:
1.类型对象指针(指向该实例所对应的类型对象)
2.同步快索引
3.该实例所含的字段
类型本质上也是对象,CLR创建类型对象时,必须初始化以上类型在分配时包含的成员,初始化成什么呢?CLR开始在一个进程中运行时,会立即为强命名程序集MSCorLib.dll中定义的System.Type类型创建一个特殊的类型对象。而我们自定义的用户类型都是该类型的“实例”。因此它们的类型对象指针成员会初始化成对System.Type类型对象的引用。
当然,System.Type类型对象本身也是对象,内部也有“类型对象指针”成员。这个指针指向什么?它指向它本身,因为System.Type类型对象本身是一个类型对象的“实例”。
而System.Object的GetType方法返回存储在指定对象的“类型对象指针”成员中的地址,即其成员变量“类型对象指针”的值。也就是说,GetType方法返回指向该对象的类型对象的指针。这样就可判断系统中任何对象(包括类型对象本身)的真实类型。