CLR(公共语言运行库)
主要作用是为我们定位、加载和管理.Net类型,同时也负责一些底层细节的工作,如内存管理,创建应用程序域、线程、和上下文边界,安全检查等。 CLR 运行库可以理解为执行给定编译代码单元所需的外部服务的集合。CLR 中最重要的是由名为mscoree.dll(又称公共对象运行库执行引擎)的库。当用户程序引用一个程序集,要使用它时,mscoree.dll将首先自动加载,然后由它负责将需要的程序集导入内存。运行时引擎需要负责许多任务,首要的任务是负责解析程序集的位置,并通过读取其中的元数据,在二进制文件中发现所请求的类型。接着,CLR 在内存中为类型布局,将关联的CLR编译成特定平台的指令,执行所有需要的安全检查,然后运行当前的代码。需要时,CLR也会与包含在.NET基类库中的类型相交互。
CTS (公共类型系统)
是一个正式的规范,它规定了类型必须怎样定义才能被CLR承载。
CTS规范完整的描述了运行库所支持的所有可能的数据类型、编程结构,指定了这些实体间的交互,也规定了它们在元数据格式中的表示。CTS定义的类型包括: CTS类类型,接口类型,结构类型,枚举类型,委托类型,类型成员是集合(构造函数,终结器,静态构造函数,嵌套类型,运算符,方法,属性,索引器,字段,常量,事件)中的元素之一,内建的数据类型等。
CLS(公共语言规范)
是一个相关的规范,定义了一个让所有的.NET语言都支持的公共类型和编程结构的子集。它描述了支持.NET 的编译器必须支持的最小的和完全的特征集,以生成可由CLR承载的代码,同时可以被基于.NET平台的其他语言通用的方式进行访问。如果使用了与CLS不兼容的数据类型和编程结构,就不能保证所有的.NET 语言能和你的.NET代码库相交互。CLS可以看成 是由CTS 定义的完整功能的一个子集。
我们可以使用 .NET 特性[assembly:System.CLSComp]iant(True)来指示C#编译器检查代码是否遵循CLS规则。
BCL(基类库) 这个类库 不仅封装了各种基本类型,如线程、文件输入/输出(I/O)、图形绘制以及与各种外部硬件设备的交互,还支持在实际应用中的一些服务。
CLR、CTS、CLS、和基类库之间的关系如下图:
C# 生成的代码 只能在.NET运行库中执行,这种必须在.net运行库执行的代码称为托管代码(managed code)。包含托管代码的二进制单元称为程序集。反之,不能直接在.net运行库承载的代码称为非托管代码(unmanaged code)。
IL、MSIL、CIL 指的是同一概念。CIL 的好处: 每种支持.NET 的编译器生成的是几乎完全相同的CIL指令,所以所有支持.NET的语言都能很好地在定义明确的二进制文件间相互交换。
.NET程序集 是一个二进制文件(*.dll 或者*.exe),它包含的是与平台无关的IL(中间语言)和类型元数据。 元数据详尽的描述了二进制文件中每个“类型” 的特征。 程序集本身也是使用元数据进行描述,这类元数据我们称它为“清单”。清单记录了程序集的当前版本信息、文化信息、(用于本地化字符串和图像资源)和正确执行所需要的外部引用程序集的列表。
将CIL编译成特定平台的指令:
由于程序集中包含的是CIL指令而不是某一特定平台的指令,所以CIL使用前必须使用即时编译器编译成有意义的CPU指令。.NET 运行库环境将使用针对各种不同CPU的JIT编译器,每个编译器都会针对底层平台进行优化。当给定的JIT编译器将CIL指令编译为相应的机器码时,它会将结果缓存在内存中。这样当一个方法被调用,则它对应的CIL指令将在第一次调用中被编译成特定平台的指令并被保留在内存中以备以后只用,因此在下一次调用这个方法时,就不需要编译CIL了。
.NET 类型元数据的作用
元数据描述了每一个二进制文件中定义的类型(类、结构、枚举等),以及每个类型的成员(属性、方法、事件等)。它不仅用于.NET 运行库环境的许多方面,而且用于各种开发工具中。例如 智能感知特性就是在设计阶段读程序集的元数据。
命名空间就是一个程序集内相关类型的一个分组。
多数.NET Framework 程序集都位于称为全局程序集缓存(GAC)的特定目录下。在安装Windows的计算机上,默认状态下,GAC位于C:\Windows\Assembly目录下。
中间语言反汇编工具(ildasm.exe)可以加载任意的.NET程序集并分析它的内容,包括关联的清单、CIL代码和类型元数据。我们也可以使用Reflector 可以查看程序集的实现。
CLI (公共语言基础设施)CLI 实现现在两个主要的派流(Mono 和 Portable)用于开发跨平台的.NET应用程序。