public sealed class Program{
public static void Main() {
System.Console.WriteLine("Hi");
}
}

程序运行时,CLR会加载并初始化它。CLR读取程序集的CLR头,查找标识了应用程序入口方法(Main)的MethodDefToken。然后,CLR会检索MethodDef元数据表,找到该方法的IL代码在文件中的偏移量,把这些IL代码JIT(just-in-time)编译成本地(native)代码。编译时会对代码进行验证以确保类型安全性。最后,将执行本地代码。下面展示了Main方法的IL代码。(运行ILDasm.exe可以生成)

.method public hidebysig static void Main() cil managed
//SIG: 00 00 01
{
.entrypoint
//Method begins at RVA 0x2050
//Code size 11 (0xb)
.maxstack
IL_0000: /* 72 | (70)000001 */
ldstr "Hi"
IL_0005: /* 28 | (0A)000003 */
call void [mscorlib]System.Console::WriteLine(string)
IL_00a: /* 2A | */
ret
}//end of method Program::Main

对这个代码进行JIT编译时,CLR会检查对类型和成员的所有引用,并加载定义了它们的程序集(如果尚未加载)。可以看出,上述IL代码有一个对System.Console.WriteLine的引用。具体地说,IL call 指令应用了token 0A000003.这个token对应于MemberRef源数据表中的记录项3.CLR检查这个MemberRef记录项,发现它的一个字段引用了一个TypeRef表中的一个记录项(System.Console类型)。根据TypeRef记录项,CLR被引导至一个AssemblyRef记录项:“mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089”.这样,CLR就知道了它需要的是哪一个程序集。接着,CLR必须定位并加载该程序集。

解析一个引用的类型时,CLR可能在以下三个地方找到类型。

  • 同一个文件
  • 不同的文件,同一个程序集
  • 不同的文件,不同的程序集

下图为一个类型绑定的图解过程:

读经典——《CLR via C#》(Jeffrey Richter著) 笔记_运行时解析类型引用的更多相关文章

  1. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_引用类型和值类型(二)

    [引用类型和值类型的区别] //引用类型(由于使用了‘class’) class SomeRef { public Int32 x; } //值类型(由于使用了‘struct’) struct Som ...

  2. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_发布者策略控制

    在 读经典——<CLR via C#>(Jeffrey Richter著) 笔记_高级管理控制(配置)中,是由程序集的发布者将程序集的一个新版本发送给管理员,后者安装程序集,并手动编辑应用 ...

  3. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_方法执行

    [前言] 方法执行前,CLR 会检测方法内代码引用的所有类型.同时 CLR 会分配一个内部数据结构,用来管理对所有引用的类型的访问. 首次执行方法时,托管程序集会把 IL 转换成本地 CPU 指令,并 ...

  4. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_元数据

    1.元数据简介 全称:metadata 属性:数据表集合 产地:面向 CLR 的编译器在托管模块中生成 2.元数据内部结构及与托管模块的关系 [概述] 托管模块中包含着元数据,元数据是由一组数据表组成 ...

  5. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_通过ILDasm.exe查看编译器如何将类型及其成员编译成元数据

    [实例代码] using System; public sealed class SomeType //-------------1 { //嵌套类 private class SomeNestedT ...

  6. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(二)

    [基元类型推荐] 推荐直接使用 FCL 类型. [理由] 编码时不至于困惑string与String的使用.由于C#的stirng(一个关键字)直接映射到System.String(一个 FCL 类型 ...

  7. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_基元类型(一)

    [概念] 编译器直接支持的数据类型 [C#基元类型与对应的 FCL 类型] C#基元类型 FCL 类型 说明 sbyte System.Sbyte 有符号8位值 byte System.Byte 无符 ...

  8. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_高级管理控制(配置)

    一个应用程序的XML配置文件示例: <?xml version="1.0"?> <configuration> <runtime> <as ...

  9. 读经典——《CLR via C#》(Jeffrey Richter著) 笔记_友元程序集

    [应用场景] 程序集A访问程序集B定义的Internal访问类型的类的成员. [使用方式] 在构建程序集B的时候,引入System.Runtime.CompilerServices,以此来添加Inte ...

随机推荐

  1. IP及端口号

    IP:代表一台机器 端口号:每一个程序都有一个端口号与之对应 一个域名对应一个虚拟主机

  2. import random随机生成验证码

    #!/usr/bin/env python import random temp = "" for i in range(6): num = random.randrange(0, ...

  3. Android禁止程序自动旋转的配置

    在想要禁止的Activity中加入 android:screenOrientation="portrait" 属性,其中,portrait是竖屏,landscape是横屏

  4. scala中同步块

    private def initializeIfNecessary() { if (!Logging.initialized) { Logging.initLock.synchronized { if ...

  5. NETTY4中的BYTEBUF 内存管理

    转 http://iteches.com/archives/65193 Netty4带来一个与众不同的特点是其ByteBuf的重现实现,老实说,java.nio.ByteBuf是我用得很不爽的一个AP ...

  6. Linux中创建和使用静态库&动态库

    库本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行 Linux下库的种类 linux下的库有两种:静态库和共享库(动态库). 二者的不同点在于代码被载入的时刻不同. 静态库的代码在 ...

  7. [学习笔记]Vfork深入理解

    #include<stdio.h> #include<stdlib.h> #include<string.h> #include <unistd.h> ...

  8. excel导入工具

    1 介绍 excel导入工具 整个项目的代码结构如下 \---excelExport # 导出工具包 | AsyncExportExcel.java #多线程导出 | ExcelImport.java ...

  9. c#操作json 使用JavaScriptSerializer

    需要引用:System.Web.Extensions /// <summary> /// json的信息.保证定义的变量和json的字段一样(也可以使用struct) /// </s ...

  10. 在GridView控件FooterTemplate内添加记录 Ver3

    重构此篇<在GridView控件FooterTemplate内添加记录 Ver2> http://www.cnblogs.com/insus/p/3270644.html 这有些缺陷,怎样 ...