了解了.NEt的结构后,我们该看看.NET利用其结构为我们创造的运行环境--公用语言运行时环境(CLR)。它是C#及其它支持.NET平台的开发工具的运行基础。具体来说,它为我们的应用提供了以下益处:
●跨语言集成的能力。
●跨语言异常处理。
●内存管理自动化。
●强化的安全措施。
●版本处理技术。
●组件交互的简化模型。
2.2.1、理解CLR
.NEt提供了一个运行时环境,叫做公用语言运行时,它管理着代码的执行,并使得开发过程变得更加简单。这是一种可操控的执行环境,其功能通过编译器与其它工具共同展现,你的代码将受益于这一环境。依靠一种以运行时为目标的(指完全支持运行时环境的)编译器所开发的代码叫做可操控代码。它得益于可操控环境的各种特性:跨语言集成、跨语言异常处理、增强的安全性、版本处理与开发支持、简单的组件交互模型以及调试服务。为了使运行时环境能够向可操控代码提供服务,语言编译器需要产生一种元数据,它将提供在你使用语言中的类型、成员、引用的信息。元数据与代码一起存储,每个可加载的CLR映像均包含了元数据。运行时环境使用元数据定位并载入类,在内存中展开对象实例,解决方法调用,产生本地代码,强制执行安全性,并建立运行时环境的边界。
运行时环境自动处理对象的展开与引用,当它们不再使用时负责它们的释放。被运行时环境进行这样的生命周期管理的对象被称为可操控代码。自动内存管理消除了内存溢出,同时也解决了其它一些常见的语法错误。如果你的代码是可操控的,你仍然可以在需要的时候使用非可控代码,或者在你的.NET应用中同时使用可控与非可控代码。由于语言编译器支持他们自己的类型,比如一些原始类型,你可能并不总是知道(也不必知道)你的数据是否是可控的。
CLR使设计跨语言的组件与应用变得更加容易。以不同语言设计的对象能够彼此间进行通信,并且它们的行为能够紧密地综合与协调。举个例子,你定义了一个类,然后可以在另一种不同的语言中从该类中派生了一个类或者调用它其中的一个方法。你也可以向另一种语言中类的方法传递该类的一个实例。这种跨语言的集成之所以可能,因为以运行时间为目标的语言编译器与工具使用一种运行时间所定义的公用类型系统,他们遵守运行时的规则(公用语言规范)来定义新的类型,生成、使用、保持并绑定类型。
作为元数据的一部分,所有可控组件携带了关于它们所依赖的组件与资源的信息。运行时环境使用这些信息来保证你的组件或应用具有需要的所有东西的特定版本,其结果是你的代码将不会因为版本冲突而崩溃。注册信息与状态数据不再保存在难以建立与维护的注册表中,你所定义的类型及附属信息作为元数据被保存,这使得复制与移动组件的复杂程度得到降低。
编译工具用他们自己的方式向开发人员展现CLR的功能。这意味着运行时间的一些特性可能在不同的语言中表现形式将会有所不同。你怎样体验运行时的特性将取决于你所使用的语言,比如说,如果你是一位VB开发人员,你可能注意到在运行时环境的帮助下,VB语言比以前具有更多的面向对象的特性。
2.2.2、可操控执行的含义
前面的叙述中,我们多次提到了“可操控”这一概念。这意味着它指向的对象在执行过程中完全被运行时环境所控制。在执行过程中,运行时环境提供以下的服务:自动内存管理、调试支持、增强的安全性及与非可操控代码的互操作性,例如COM组件。
在可控执行进程中的第一步是选择源代码的生成工具。如果你希望你的应用拥有CLR提供的优势,你必须使用一种(或多种)以运行时为目标的语言编辑器,例如:VB、C#、VC的编译器,或者一种第三方编译器如PERL或COBOL编译器。
由于运行时是一种多语言执行环境,它支持众多的数据类型和语言特性。你使用的语言编译器决定你将使用运行时的哪一部分功能子集。在代码中使用的语法由你的编译器决定,而不是运行时环境。如果你的组件需要被其他语言的组件完全使用,那么你必须在你组件的输出类型中使用CLR所要求的语言特征。
当你完成并编译你的代码时,编译器将它转换为微软中间语言(Microsoft Intermediate Language,MSIL),同时产生元数据。当你要执行你的代码时,这种中间语言被即时(Just In Time,JIT)编译器编译成本地代码。如果安全策略需要的代码是类型安全的---通常情况下都是如此---JIT编译器将在编译进程中对中间语言进行类型检查。一旦失败,在代码执行中将会触发异常。