C#学习笔记

学习C#的时候看到许多觉得重要的知识点,在此把他们记录下来。

  • 元数据

  • CLR执行程序集的代码

  • 类型转换


元数据

托管模块组成部分:

  1. 标准Windows PE文件头。对平台,文件类型(GUI,CUI,DLL),生成时间等进行记录。
  2. CLR头。CLR版本,一些标志(Flag),托管模块入口方法(Main方法)的MethodDef元数据token,以及模块的元数据,资源,强名称等。
  3. 元数据。每个托管模块都包含元数据表。
  4. IL代码。

元数据简单来说是一个数据表合集,一些数据表描述了模块中定义了什么(比如类型及其成员),另一些描述了模块引用了什么(比如导入的类型及其成成员)。元数据总是与包含IL代码的文件关联,总是嵌入和代码相同的EXE/DLL文件中,使两者密不可分。由于元数据同时生成元数据和代码,把它们绑定在一起,并嵌入最终生成的托管模块,所以元数据与它描述的IL代码永远不会失去同步。

CLR执行程序集的代码

CLR的JIT(just-in-time,即时)编译器负责将生成的IL转换成本机native的CPU指令。代码开始运行之前,CLR会检测代码块引用的所有类型,并分配一个内部数据结构管理对引用类型的访问。

代码中使用引用类型->CLR分配一个内部结构,代码中每个引用类型都有一个Entry->目前Entry指向一个JITCompiler。

当首次调用到该代码块时候,JIT编译器被调用。按照以下顺序执行:

  1. 找到被调用的方法的元数据(metadata)。
  2. 从元数据中获取该方法的IL。
  3. 分配内存块。
  4. 将IL编译成本机CPU指令,然后将这些本机代码储存在内存块中。
  5. 在内部结构中修改最初指向JITCompiler的引用,使其指向内存块。
  6. 跳转到内存块的本机代码。

第二次调用的时候会直接掉过JIT Compiler,直接执行内存中的本机代码。

类型转换

System.Object中一个公共方法GetType用来指示对象类型。它返回指定对象的“类型对象指针”成员中的地址,也就是对象的对象类型的指针,因此可以判断系统中任何对象(包括类型对象本身)的真实类型。

**栈中的对象指针 -> **

**堆中的对象实例,包括了类型对象指针,同步块索引和实例字段,其中__类型对象指针__指向 -> **

类型对象,包括类型对象指针(指向System.Type类型对象,而后者的类型对象指针则指向自己),同步块索引、静态字段和方法。

由于有类型对象指针,因此C#可以做到安全的类型转换。

is操作符检查对象是否兼容,返回一个布尔值。

as相当于使用is操作符作if判断,为true返回一个转型后的引用,否则返回null。

as只需要一次遍历继承层次结构,is并手动转形需要两次。

基元类型、引用类型和值类型

资料参考《CLR Via C#》Jeffrey Richter 著 周靖 译 清华大学出版社

posted @ 2018-12-23 17:25  威化饼干  阅读(228)  评论(0编辑  收藏  举报