C#学习笔记
学习C#的时候看到许多觉得重要的知识点,在此把他们记录下来。
-
元数据
-
CLR执行程序集的代码
-
类型转换
元数据
托管模块组成部分:
- 标准Windows PE文件头。对平台,文件类型(GUI,CUI,DLL),生成时间等进行记录。
- CLR头。CLR版本,一些标志(Flag),托管模块入口方法(Main方法)的MethodDef元数据token,以及模块的元数据,资源,强名称等。
- 元数据。每个托管模块都包含元数据表。
- IL代码。
元数据简单来说是一个数据表合集,一些数据表描述了模块中定义了什么(比如类型及其成员),另一些描述了模块引用了什么(比如导入的类型及其成成员)。元数据总是与包含IL代码的文件关联,总是嵌入和代码相同的EXE/DLL文件中,使两者密不可分。由于元数据同时生成元数据和代码,把它们绑定在一起,并嵌入最终生成的托管模块,所以元数据与它描述的IL代码永远不会失去同步。
CLR执行程序集的代码
CLR的JIT(just-in-time,即时)编译器负责将生成的IL转换成本机native的CPU指令。代码开始运行之前,CLR会检测代码块引用的所有类型,并分配一个内部数据结构管理对引用类型的访问。
代码中使用引用类型->CLR分配一个内部结构,代码中每个引用类型都有一个Entry->目前Entry指向一个JITCompiler。
当首次调用到该代码块时候,JIT编译器被调用。按照以下顺序执行:
- 找到被调用的方法的元数据(metadata)。
- 从元数据中获取该方法的IL。
- 分配内存块。
- 将IL编译成本机CPU指令,然后将这些本机代码储存在内存块中。
- 在内部结构中修改最初指向JITCompiler的引用,使其指向内存块。
- 跳转到内存块的本机代码。
第二次调用的时候会直接掉过JIT Compiler,直接执行内存中的本机代码。
类型转换
System.Object中一个公共方法GetType用来指示对象类型。它返回指定对象的“类型对象指针”成员中的地址,也就是对象的对象类型的指针,因此可以判断系统中任何对象(包括类型对象本身)的真实类型。
**栈中的对象指针 -> **
**堆中的对象实例,包括了类型对象指针,同步块索引和实例字段,其中__类型对象指针__指向 -> **
类型对象,包括类型对象指针(指向System.Type类型对象,而后者的类型对象指针则指向自己),同步块索引、静态字段和方法。
由于有类型对象指针,因此C#可以做到安全的类型转换。
is操作符检查对象是否兼容,返回一个布尔值。
as相当于使用is操作符作if判断,为true返回一个转型后的引用,否则返回null。
as只需要一次遍历继承层次结构,is并手动转形需要两次。
基元类型、引用类型和值类型
资料参考《CLR Via C#》Jeffrey Richter 著 周靖 译 清华大学出版社