.NET是微软的新一代技术平台。对技术人员来说,想真正了解什么是.NET,须先了解.NET技术出现的原因和它想解决的问题。时间追溯到20世纪90年代末,当时在微软Windows平台上编程的程序员分为Win32 API、MFC和COM三大派。Win32 API是微软向程序员开放的应用程序函数编程接口,函数多,零散繁琐,开发工作量大;MFC是对API进行分类封装的基础框架,开发者只需知道如何调用即可;COM是一种二进制、网络标准,允许两个联通的组件相互通信而无需考虑该组件是由什么语言实现,只要该机器支持COM标准。这些技术都有着各自的优缺点,但是这些技术都有着一个共同的缺点,它们主要针对的是桌面程序,而不是Internet开发。下面以COM技术为例对比其和.NET的特点:
1.COM中,所有的对象必须实现IUnknown接口,而在.NET中所有对象是实现Object类。接口编程在.NET中虽然是一个重要组成部分,但是已不是中心主题。
2.COM中类型信息作为.tlb文件保存在类型库中,它和可执行代码是分开的。而.NET中是将程序类型信息和可执行代码保存在一个程序文件中。
3.COM中程序员必须记录一个对象在程序中的引用数目,从而确保在所有的引用结束后将该对象删除。而在.NET中,垃圾回收器 (GC) 会自动记录对象的引用情况,实现自动管理,并在合适的时机删除无主对象。
4.COM使用HRESULT数据类型返回运行时错误代码。而.NET不再使用该类型,其中的运行时错误都当做异常处理,这样使得代码的运行更加安全。
5.COM的应用必须在系统注册表中注册。注册表中保存了与操作系统的配置和应用程序有关的信息。.NET应用不再需要注册COM对象,这使得程序的安装卸载操作变得更加简单 (但.NET中存在全局程序集缓存GAC这一概念)。
新一代的.NET平台希望形成一个集成的、面向对象的开发框架,使得代码的开发环境具有面向对象、一致的编程体验、行业标准通信(XML, HTTP, SOAP, JSON, WSDL)、程序部署简单、语言独立、互操作六大特点,代码的执行环境能够达到多平台(从服务器、PC机到PDA)、既安全又高效。较之前的Windows编程环境,.NET框架为程序员带来了相当大的改进,主要表现在以下4个方面:
1.面向对象的开发环境。系统为本地程序和分布式系统都提供了一致的、面向对象的编程模型。此外,还为桌面应用程序、移动应用程序、Web开发提供了软件开发接口,设计的目标范围很广,从桌面服务器到手机。
2.垃圾自动回收。程序员可以从记录程序对象的引用个数这样的繁杂工作中解脱出来,不再需要执行释放内存和检查内存泄露这样的工作。.NET框架可以实现自动管理内存,自动从内存中删除程序不再访问的对象。
3. 互操作性。.NET语言的互操作性表现在不同的.NET语言、不同的操作系统平台,.NET语言和Win32 DLL、.NET语言和COM之间。
①.NET语言的互操作。允许用不同的.NET语言编写的软件模块无缝交互,一种.NET语言写的程序可以使用另一种语言写的类,真正做到语言无关。
②平台调用(Platform invoke)。在.NET的代码和非.NET语言写的代码之间交互,实现调用。例如可以在C#的代码中直接调用标准的Win32 DLL到处的纯C函数代码。
③与COM对象互操作。.NET组件可以实现COM组件的互相调用。
4.程序的部署。.NET框架编写的程序与使用其他技术实现的程序部署要容易得多。一方面,.NET程序不需要在注册表中登记信息,这使得程序可以直接拷贝到目标机器上便可以运行;另一方面,.NET提供并行执行的功能,允许DLL的多个版本在同一台机器上同时存在,这使得每个可执行的程序都可以访问程序生成时的那个版本的DLL,而不会因为一个程序的升级,使得其他程序无法使用的情况发生。
目前越来越多的程序员开始将目光投向了.NET,这也使得微软在最近几年出现了不少新的动作。今年4月微软宣布开源一批.NET库和相关技术,11月微软表示将不再把.NET和Visual Studio等关键软件技术局限在Windows平台,今后还将兼容Linux、Mac OS X、iOS和Android。
在了解.NET技术出现的原因和它想解决的问题后。下面将对.NET框架的各个组成部分进行一一介绍,以让大家熟悉.NET框架的基本概念,也为将来在.NET平台上做应用开发奠定基础。
如果把开发工具也包括进来的话,.NET框架由以下四个部分组成。
- Visual Studio集成开发环境IDE(Integration Development Environment),.NET的代码开发环境,负责编译时程序源代码的编写、编译、调试和软件部署。
- 基础类库BCL(Basic Class Language ),在编写程序时可以直接调用这些预定义的类。
- 公共语言运行库CLR(Common Language Runtime),.NET的代码执行环境,负责运行时管理程序的执行
- 公共语言基础结构CLI(Common Language Infrastructure),包括公共类型系统CTS(Common Type System)和公共语言规范CLS(Common Language Specification),为让不同语言编写的程序及库能够在.NET框架中进行良好地协作所约定的一套标准规范。
很多高级语言都需要通过编译器编译成机器语言的目标程序才能在目标机器上执行,.NET语言也不例外,但是.NET语言的编译器在接受源代码后并不是直接编译成机器代码,而是生成中间语言CIL(Common Intermediate Language)的程序集文件,这个程序集可以是可执行的或者DLL。程序集中包括程序编译的CIL,程序中使用的类型元数据和对其他程序集引用的元数据(如图1)。
.NET中的编译器有两类。一类叫做.NET兼容编译器,它主要是实现将.NET兼容语言编译成中间语言CIL的程序集,另一种称为实时编译器JIT(Just in Time),这种编译器在程序被调用时将CIL编译成本机代码。前者是在编译阶段执行,后者是在运行时执行。
在第二次编译时,程序集中的可执行代码只在需要的时候由JIT编译器编译,编译后将会在内存中缓存起来以备后来的程序执行。这也就意味着不被调用的代码不会被编译成本机代码,而且被调用到的代码只被编译一次。
图1 编译时和运行时过程概览
如果把.NET框架比作为一个社会的话,各种.NET兼容语言就是这个社会中使用的交流语言。因为每种编程语言都有一组内置的类型,用来表示整数、浮点数和字符等基本类型,这些类型的特征因编程语言和平台的不同而不同。为了让不同的语言编写的程序及库能在一起良好地协作,需要有一组这样的标准来约定。
公共语言基础结构CLI(Common Language Infrastructure)就是这样一组标准,它把所有.NET框架的组件连接成一个内聚的、一致的系统。它展示了系统的概念和架构,并详细说明了所有软件必须坚持的规则和约定。CLI包括公共类型系统CTS(Common Type System)和公共语言规范CLS(Common Language Specification)。CTS主要是对托管代码进行了约定,包括丰富的内置类型以及每种类型固有的、特有的性质,规定所有的类型都继承自公共的基类Object类。有了CLS,可以使用任何.NET兼容语言进行互操作,而不会出现系统类型和用户自定义类型之间的冲突。
这四个组成部分中,核心组件是公共语言运行库CLR,这也是.NET能实现其开发环境和执行环境特点的核心技术所在,它在操作系统的顶层,负责管理程序的执行。CLR是在程序的运行时执行包括检查程序集的安全特性、内存分配、在程序被调用时将程序集中的被调用部分可执行代码发送给实时编译器JIT。一旦程序CIL编译成本机代码,CLR就在它运行时管理它,执行像释放无主内存、检查数组边界、检查参数类型和管理异常等任务。因此,也产生了两个重要的术语:托管代码和非托管代码。
托管代码(Managed Code) —— 指的是.NET框架编写的代码,需要CLR进行管理。
非托管代码(Unmanaged Code) —— 不再CLR控制之下运行的代码,比如Win32 C / C++ DLL。
图2 CLR概览
术语表
缩写 | 全称 | 中文 |
API | Application Program Interface | 应用程序接口 |
MFC | Microsoft Framework Class | 微软框架类 |
COM | Component | 组件 |
GAC | Global Assemble Cache | 全局程序集缓存 |
GC | Garbage Collector | 垃圾回收器 |
IDE | Integrated Development Environment | 集成开发环境 |
BCL | Base Class Library | 基础类库 |
CLR | Common Language Runtime | 公用语言运行库 |
CLI | Common Language Infrastructure | 公共语言基础结构 |
JIT | Just in Time | 试试编译器 |
DLL | Dynamic Linkable Library | 动态链接库 |
CTS | Common Type System | 公共类型系统 |
CLS | Common Language Specification | 公用语言规范 |