购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.2 .NET平台简介

微软在2000年7月发布了新的应用平台.NET,整个.NET平台包括4部分产品。

(1).NET开发工具。 .NET开发工具由.NET语言(C#、VB.NET)、一个集成的IDE(Visual Studio.NET)、类库和通用语言运行时(CLR)构成。

(2).NET专用服务器。 .NET专用服务器由一些.NET企业服务器组成,如SQLServer 2000、Exchange 2000、BizTalk 2000等。这些企业服务器可以为数据存储、E-mail、B2B电子商务等专用服务提供支持。

(3).NET Web服务。 虽然Web Service不是.NET所特有(关于Web Service内容请见第6章),但.NET为Web Service提供了强有力的支持。开发者使用.NET平台可以很容易的开发Web Service。

(4).NET设备。 作为同J2ME(Java 2 Micro Edition)竞争的部分,.NET还为手持设备,如手机等,提供了支持。

完整的.NET平台涵盖了JVM、J2SE和J2EE全部的内容。.NET平台出现的时间较短,大多数读者对.NET底层的了解少于Java虚拟机。故5.2节主要介绍.NET的底层机制,基本上同JVM相对应。在5.3节的对比分析中会引入.NET平台在开发企业应用中的框架和作用。

5.2.1 .NET平台概述

Microsoft .NET平台包括五个部分,如图5-5所示。

图5-5 Microsoft .NET平台

5.2.2 .NET Framework

.NET Framework中引入一系列的新技术和新概念,图5-6给出了.NET Framework的结构图。其中核心的部分就是通用语言运行时——CLR(Common Language Runtime)。CLR是.NET程序的执行引擎,.NET的众多优点也是由CLR所赋予的。CLR同JVM的功能类似,提供了单一的运行环境。任何.NET应用程序都会被最终编译为中间语言IL(Intermediate Language),并在这个统一的环境中运行。也就是说CLR可以用于任何针对它的编程语言,这也就是.NET的多语言支持。CLR还负责.NET应用程序的内存管理、对象生命期的管理、线程管理、安全等一系列的服务。我们将在5.2.3节详细介绍CLR。

图5-6 .NET Framework组成结构

除了CLR外,.NET提供了.NET类库,每一种.NET语言都可以使用该类库。基本类库中包含了大量的类供开发者使用,如图5-6所示。除此之外,使用某种.NET语言开发的类可以被其他的.NET语言直接使用,从而充分利用各种语言的优点。这也就是说我们可以使用VB.NET书写UI(User Interface)相关的内容,而底层的计算功能是用C++开发。.NET Framework还对命名空间提供了支持,熟悉Java的程序员一定非常欣赏Java中清晰的类的层次结构,.NET Framework中的命名空间与之类似,非常适合组织大规模的类的层次结果。如System.Data,或者由开发者自定的Abc. Accounting.Service。

5.2.3 通用语言运行时CLR

1.托管

托管是.NET的一个专门概念,它是融于通用语言运行时(CLR)中的一种新的编程理念,使用托管意味着代码可以被CLR所管理,使用CLR提供的各种服务。无论是用什么语言,只要采用了.NET的托管机制,就能开发出具有最新特性如垃圾自动收集、程序间相互访问等的.NET框架应用程序。

所有的C#、VB.NET、JScript.NET默认时都是托管的,但Visual C++默认时不是托管的,也就是非托管C++,必须在编译器中使用选项才能产生托管代码。由托管概念所引发的托管应用程序包括托管代码、托管数据和托管类三个组成部分。

(1)托管代码: .Net环境提供了许多核心的运行(Runtime)服务,比如异常处理和安全策略。为了能使用这些服务,必须给运行环境提供一些信息代码(元数据),这种代码就是托管代码。

(2)托管数据: 与托管代码密切相关的是托管数据。托管数据是由公共语言运行的垃圾回收器进行分配和释放的数据。在默认情况下,C#、Visual Basic 和 JScript.NET数据是托管数据。不过,通过使用特殊的关键字,C# 数据可以被标记为非托管数据,Visual C++数据在默认情况下是非托管数据。

(3)托管类: 尽管Visual C++数据在默认情况下是非托管数据,但是在使用C++的托管扩展时,可以使用“_gc”关键字将类标记为托管类。就像该名称所显示的那样,它表示类实例的内存由垃圾回收器管理。另外,一个托管类也完全可以成为 .NET框架的成员,由此可以带来的好处是,它可以与其他语言编写的类正确地进行相互操作,如托管的C++类可以从Visual Basic类继承等。但同时也有一些限制,如托管类只能从一个基类继承等。需要说明的是,在托管C++应用程序中既可使用托管类也可以使用非托管类。这里的非托管类不是指标准C++类,而是使用托管C++语言中的_nogc关键字的类。

2.程序集

程序集是一个抽象的概念,也比较难于理解。我们可以这样理解程序集的概念:首先,程序集是一个或多个托管模块或资源文件的逻辑分组;其次,程序集是可重新使用、确保安全和版本控制的最小单元。图5-7是把托管模块组合称为程序集的示意图。

图5-7 将托管模块组合为程序集

程序集允许我们将可重用、可部署的组件的逻辑部分和物理部分相分离。例如,可以将不常用的类型或资源放到独立的程序集文件中,这些独立的文件可以根据需要从Web站点上动态下载。如果不需要使用这些程序集,那么就永远不需要下载这些文件。

程序集中还包含被引用的程序集的自描述信息——如版本号。由于CLR可以通过这些自描述信息执行程序而不需要其他的附加信息。因此程序集使得.NET应用更容易部署。

3.中间语言

当托管代码被编译后,并不产生本机的二进制代码,而是产生包含中间语言IL(Intermediate Language)的程序集。每种托管语言(C#,VB.NET等)都产生中间语言程序集,IL为被编译的代码提供一种通用的表示。Microsoft宣称,编译为IL的代码可以运行在任何使用.NET Framework的处理器和操作系统中(其实也只用Windows和X86-笔者注),不过包含IL的程序集可以非常容易地运行于Windows 98或者WindowsME,从而为.NET提供更多的应用平台。

被编译为IL语言的程序集不能够直接运行,CLR中使用JIT(just-in-time)编译器将IL转化为本机的CPU指令。图5-8显示了首次调用一个方法的执行过程。

JIT(just-in-time) Compiler负责将IL代码编译成本机的CPU指令,因为JIT是在程序第一次运行时实时的编译,所以JIT也称作实时编译器。只有当程序第一次运行时,JIT才会工作,它会把编译好的本机指令放在内存中,也就是说,程序在第一次运行的时候速度相对较慢,而以后的运行速度会加快很多。但是,如果程序终止,随着程序退出内存空间,编译好的本机指令也会随之退出内存,那么重新启动应用程序会再一次启动编译过程。如果程序的运行平台已经确定同时对性能有较高的要求,.NET Framework提供了一个小工具——NGen.exe,这个工具可以将所有程序集的IL代码编译成本机代码并将编译好的本机代码保存在磁盘中。这样,CLR可以在加载程序集时加载这个预编译的代码,从而提高运行速度。

图5-8 首次调用方法的执行过程

当把IL编译成本机代码时,IL会执行验证的过程。验证会检查IL的代码并确保它们的安全性,例如:验证过程会检查被调用的方法参数和参数的类型是否匹配,检查方法的返回值是否被正确使用等。如果验证结果认为IL代码是“不安全的”则会抛出System.Security.VerificationException异常并阻止方法的执行。

4.通用类型系统

因为.NET统一地对待所有的语言,所以在.NET中,要求使用C#书写的类同使用VB.NET书写的类能够互相使用,使用托管C++和托管COBOL编写的接口也完全一样。由于所有的语言必须拥有共同的标准才能够顺利地集成到一起,因此Microsoft定义了通用类型系统CTS(Common Type System)来规范每一个.NET语言。有人认为CTS是CLR中最核心的部分,因为如果没有CTS的存在,.NET的语言无关性就得不到体现。

CTS中包括很多类型,下面我们介绍其中较为重要的几种类型:值类型、引用类型、类和接口,以及委托。

5.通用语言规范

我们都知道,每种语言都有自己的特性,例如有些语言(C++)是大小写敏感的,而VB则不区分大小写,为了实现语言级的继承,Microsoft还制订了通用语言规范(Common Language Specification,CLS)。CLS提供了可以作为.NET语言的最小特性集,任何.NET语言都必须支持这些特性。从语言特性角度考虑,CLR/CLS与各种.NET语言和CLS的关系如图5-9所示。

图5-9 CLS与.NET语言的关系

CLR/CLS提供了最广泛的语言特性,仅有极个别的语言可以完全实现这些特性,如中间语言IL,一般的.NET语言都是CLR/CLS的子集,这些语言都必须包含一个共同的子集CLS——也是.NET语言的最小特性集。如果需要使用多种语言混合开发,那么程序员就需要遵守CLS以保证书写的程序的互操作性。

6.垃圾收集

.NET的垃圾收集机制与Java非常类似,但也有一些区别。.NET将内存分为托管区域和非托管区域,.NET中的垃圾收集器仅负责托管区域中的垃圾收集,同Java中的技术类似,.NET的垃圾收集器也是自动回收不可达的对象,同样也采用了分代复制的算法。但在具体实现中有细微的差别。 SH2IM9VRLjlT2/6PR1H2wT+AZmQ+QQey/D1wMv7bNlAjHOibh+ani9pAw0Ry1q1V

点击中间区域
呼出菜单
上一章
目录
下一章
×