.NET 4.0面向对象编程漫谈:基础篇
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

1.1 .NET概述

作为一本专门介绍.NET面向对象编程技术的书,必须首先要向读者讲清楚.NET是什么。

.NET其实是一个很宽泛的概念,它几乎包容了微软公司正在研发或已经得到广泛应用的各种软件开发技术有关.NET这一单词的确切含义,恐怕连微软公司自己的员工也说不清。《Understanding.NET》的作者David Chappell认为:.NET主要包括.NET Framework和Visual Studio两部分。

我们其实不必纠缠于“.NET到底包容什么”这个问题,对.NET程序员来说,应主要关心以下这几个方面:

1).NET Framework:这是微软推出的新一代软件开发与运行平台,为其他所有的.NET技术产品提供坚实的基础,从应用程序开发的角度看,.NET Framework是Win32平台的接替者。新开发的基于Windows平台的应用软件系统,大多数运行于.NET Framework之上。可以这样说,.NET Framework是.NET技术的载体,没有这一载体,.NET技术仅具有理论上的意义。

2)一组根据.NET Framework特性改造过的编程语言和开发工具。

.NET编程语言包括改进过的Visual Basic(改称为Visual Basic.NET),还有新设计的C#,以及到.NET 4.0才加入的F#,原有的C++也经过了大规模的革新,以提供开发托管.NET应用程序的新功能。传统的各种编程语言有许多都已经或正在被移植到.NET平台,.NET平台编程语言的种类一直在不断地增加中。

Visual Studio是最主要的.NET开发工具,历经微软公司持续多年的完善,已经成为世界一流的“软件集成开发环境(Integrated Development Environment,IDE)”。

3)与.NET Framework相关、基于.NET Framework或包容.NET技术的多种软件产品,包括操作系统Windows、数据库服务器SQL Server、已经成长为一个商业应用开发与运行平台的Office、全新的云计算平台Azure等,几乎包容了微软公司所有主要软件产品。

经过十多年的发展,.NET已经形成了一个庞大的技术体系,并且还在不断地引入最新的软件理论与技术成果,其前进的脚步从未停止。

笔者学习与研究.NET技术多年,想与读者分享的一个重要体会就是:

学习与掌握面向对象理论和基础技术,是学好用好.NET技术的关键。

为什么这么说?有以下几点理由:

1).NET平台本身是一个面向对象理论与技术成果的集大成者,大多数.NET技术都可归属于面向对象的范畴。

2)不对面向对象理论有深刻的理解,不可能真正了解和掌握.NET平台各项技术的技术内幕和运作机理,如果对技术只知其然而不知其所以然,很难真正用好这些技术。

3).NET平台一直处于快速发展之中,老的技术在持续完善,新的技术不断出现,不掌握好面向对象理论与基础技术,很难追上技术更新的步伐,会陷入“疲于奔命”和“见木不见林”的窘境。

4)不掌握面向对象的软件系统分析与设计方法,不了解面向对象的软件开发过程,不可能开发出好的.NET应用程序。面向对象早已经成为主流的软件开发方式,当前大多数软件系统与产品都需要应用面向对象理论与技术的成果。

5)面向对象还是新一代软件开发技术的基础与“前辈”,比如“面向服务架构(Service-Oriented Architecture,SOA)”和云计算,二者都与面向对象理论与基础技术有着千丝万缕的联系。

在阅读本书的过程中,相信读者会同意笔者上述观点的。

1.1.1 前世今生——.NET的发展历程

.NET从构思到最终成型经历了一个较长的酝酿和开发周期。据Wikipedia提供的资料,微软在上个世纪90年代末期开始.NET的开发,当时取名“下一代的Windowse服务(Next Generation Windows Services,NGWS)”,并于2000年下半年发布.NET 1.0的第一个Beta版本,而就从那时开始,.NET一步一个脚印,从幕后走向前台,最终成为了Windows技术舞台的核心主角之一。

我们先来回顾一下.NET各版本所走过的历程(见图1-1)。

2000年,微软公司向业界展示了.NET Framework 1.0的测试版,在此之前,微软公司一直在各种场合宣传.NET技术的优良特性与强大威力,却始终“犹抱琵琶半遮面”。.NET Framework 1.0测试版的发布,终于让软件工程师们一睹其“庐山真面目”,很快地在业界掀起了一场学习与研究.NET技术的热潮,虽然当时还没有软件公司立即将自己的商业产品移植到.NET平台之上,但软件巨人微软的一举一动无疑是众人关注的焦点。

图1-1 .NET各版本的历史回顾与功能扩充程度

2000年NET Framework 1.0测试版发布时,微软只提供了一些最基本的开发工具和文档,比如Visual Basic.NET与C#语言编译器,但并未提供一个好的代码编辑器。当时,要想编写.NET程序,只能找一些第三方的编辑器(比如UltraEdit)完成代码的编写工作,再手动使用相应的语言编译器生成可执行程序文件,很不方便。

2002年2月,微软发布.NET Framework 1.0正式版,与此同时,自从1998年之后就再无大动作的Visual Studio也推出了新的7.0版本,改称为Visual Studio 2002。Visual Studio 2002是微软在开发工具上积累四年之后的一次大革新,全面支持基于.NET平台的各种应用程序开发。

.NET 1.0正式版的发布虽具有“开创性”的意义,但从技术角度而言,这一新的技术平台还很不完善,为此微软公司马不停蹄地对它进行改进,于2003年4月推出了.NET Framework 1.1,相应地Visual Sudio也升级到7.1版本,称为Visual Studio 2003。1.1版本的.NET Framework较1.0的改进非常明显,在随后的两年里,Windows应用软件开发厂商开始逐步地基于这一平台开发新的软件系统和产品。

2005年11月,.NET Framework 2.0发布,与 1.1版本相比,类库更为全面丰富,增强了代码的安全性,程序性能与速度也较前有所提升,为.NET编程语言(如C#和Visual Basic.NET)添加了新的语法特性(比如泛型)。与此同时,Visual Studio也升级到版本8.0,称为Visual Studio 2005,其中引人注目之处是集成了许多软件工程工具(比如单元测试、分布式系统设计器等),使之成为Visual Studio历史上对团队开发支持最好的版本。

.NET 2.0在.NET历史上是一个重要的里程碑,正是从这一版本开始,.NET成为了一个成熟稳定的开发平台,业界开始大规模地开发基于.NET平台的软件项目和产品。

2006年11月底,微软公司发布新一代的操作系统Vista,其中集成了.NET Framework 3.0。.NET Framework 3.0在2.0的基础之上增加了Windows Presentation Foundation(简称WPF)、Windows Communication Foundation(简称WCF)、Windows CardSpace和Windows Workflow Foundation(简称WF)四项新技术,但相应版本的Visual Studio未能同步跟进,开发者必须给Visual Studio 2005单独安装扩充的插件,才能开发.NET 3.0应用程序。

WF、WCF和WPF等新技术虽然“看上去很酷”,但在如此短的时间内如此密集地推出这么多的新技术,脚步过大了一些,而且如同微软过去推出的许多其他技术一样,当时这些技术还不算成熟,各方面的表现并不令人满意,因此.NET 3.0的推广不算成功,许多软件开发企业对升级到.NET 3.0持观望态度。另一方面,直接集成.NET 3.0的Windows Vista由于存在着软件兼容性和对硬件要求高等问题,日子也并不好过,许多用户都继续使用Windows XP。

.NET 3.0和Vista遭受到了从开发者到普通用户的共同冷遇。

痛定思痛,微软下决心要在.NET 3.0的下一个版本中“扳回一局”,于2007年11月发布了.NET 3.5。正如.NET 1.1版相对于1.0版一样,.NET 3.5可以看成是.NET 3.0的稳定版本。

.NET 3.5除了完善3.0版中新加的WPF、WCF等技术之外,最大的亮点是引入了“LINQ(Language Integrated Query,语言集成查询)”,并为了支持LINQ这一技术创新,不仅给.NET基类库添加了新的组件,而且还直接地修改了C#和Visual Basic.NET等.NET编程语言,添加了新的关键字(比如C#中用于定义隐式类型变量的关键字var)和语法特性(比如对Lambda表达式的支持)。

伴随着.NET 3.5,Visual Studio也推出了相应的9.0版本,称为“Visual Studio 2008”。

微软稍后于2008年8月发布的.NET 3.5 SP1并不算引人注目,它只是“悄悄地”对基类库进行了一些改进,增加了一些组件和功能,而底层仍然沿用.NET 2.0以来的公共语言运行时(Common Language Runtime,CLR)“公共语言运行时”是中文版MSDN对CLR的译法,但另一个中文译法“通用语言运行时”也非常流行,两者是一回事。

.NET 3.5 SP1比较大的变化主要体现在两个方面:

1)在数据存取技术上,引入了“ADO.NET Entity Framework(ADO.NET实体框架)”和“ADO.NET Data Services后来改名为“WCF Data Services”。(ADO.NET数据服务)”这两项非常重要的技术。

2)为ASP.NET添加了“动态数据(Dynamic Data)”和“路由(Routing)”两个新特性,同时在Visual Studio 2008中集成了开发ASP.NET MVCMVC是“Model(模型)-View(视图)-Controller(控制器)”的缩写,是一种“设计模式(Design Pattern)”,在实际开发中应用很广。项目的功能。

有趣的是,微软对Vista也同步进行了完善,于2009年推出了Windows 7。Windows 7直接集成.NET 3.5,从预发布版本开始就广受好评,被看作是Windows XP的最佳继承者。

2010年,.NET 4.0推出,这一版本带来了一大批的新技术,甚至直接将.NET 2.0以来未曾改变的CLR都升级到了4.0,并添加了一个新的“运行时”,称为“动态语言运行时(Dynamic Language Runtime,DLR)”,变化之大,为.NET 先期版本所未见。

相应地,Visual Studio也升级到了10.0,称为“Visual Studio 2010”,为开发各种.NET 4.0应用程序提供了相应的项目模板(比如Silverlight 3通过单独安装Silverlight4 Tools For Visual Studio 2010,可以开发Silverlight 4应用程序。本书中所有的Silverlight示例均针对Silverlight 4。和ASP.NET MVC 2)。

Visual Studio 2010最大的新闻之一是它使用WPF技术开发,这向开发者发出了一个明确的信号,微软已下决心用WPF替代原有的Windows Forms。

.NET 4.0是.NET技术发展史中继.NET 2.0之后又一个重要的里程碑,它实际上标志着一轮新技术浪潮的到来,可以看成是微软在软件技术发展的下一个十年里争夺软件技术制高点的利器。

技术春秋

最初的故事——.NET诞生记改编自李开复自传《世界因你不同》

1999年前后,互联网有了爆发性的增长,在这个时代背景下,微软的“掌门人”比尔·盖茨一直在思索着一个对微软公司的发展非常关键的问题——微软是继续专注于Windows,还是向互联网发展,将微软的各种软件产品移植到互联网上?

比尔·盖茨认为,互联网是一个大趋势,于是成立了一个.NET部门进行这方面的探索。

被命名为.NET的新战略就是所谓的“新一代网络平台”,这其实就是互联网时代的“视窗”。将来的视窗包括无线通信、智能家电,也包括新一代的人机界面,而更多的终端将可以实现互联网的功能。

比尔·盖茨的这个决定在微软公司内部引发了激烈的争论,Windows的“元老们”对Windows怀有很深的感情,无法容忍任何一件动摇这一产品在公司产品线核心地位的事情发生,而另一批“变革派”则认为:网络将盖过Windows,浏览器将变成一个平台,将会有越来越多的软件在浏览器中运行,因此微软公司应该将Windows的功能逐步移到浏览器上,并冻结对Windows的进一步投资,因为Windows即将完成它的历史使命,会在十年内走到它的生命尽头。

简单地说,.NET战略最初的构想是:微软将开发一个“超级浏览器”,它可以运行所有软件。很明显,.NET战略过于激进了,在大多数情况下,技术上的创新往往建立于原有技术基础之上,完全抛弃原有的东西既不可能也不必要。

在“保守派”与“变革派”激烈的争论中,比尔·盖茨最终做了妥协,取消原先的.NET计划,仍将重点放到Windows上,并且决定将.NET建构于Windows之上。

所以,作为一个妥协的产物,.NET从Windows的“挑战者”变成了“合作者”,它的角色定位为一个新的Windows应用软件运行平台。

1.1.2 .NET Framework与Windows操作系统

在微软的历史上,Windows XP绝对是一个经典,XP建构于NT技术之上,而NT技术在上世纪80年代末期开始研发,迄今已有超过20年的历史。近十年以来,以NT技术为核心的Windows操作系统微软于2009年推出的Windows 7,其核心仍然是NT,其版本为6.1,国内翻译出版了一本名为《观止——微软创建NT和未来的夺命狂奔》的书,其中详尽地介绍了微软公司开发NT的艰辛历程。取得了巨大的成功,有大量的应用软件运行在包容着NT内核的Windows操作系统之上。

当前,个人电脑上占主流地位的是32位的Windows操作系统(包括XP、Vista和Windows 7)64位的Windows早已推出,但由于当前64位的计算机并未完全替代32位的计算机,而且现有大量的软件是32位的,其升级过程比较漫长,因此,当前64位的Windows还未成为主流。不过,开发64位的软件是一个大趋势。,操作系统的功能由数千个C/C++格式的函数进行了封装,供应用程序调用。软件工程师习惯把NT平台所提供的这数千个C/C++函数统称为“Win32 API(Application Program Interface,应用程序编程接口)”。在NT平台上开发的软件,都直接或间接地调用了Win32 API函数。

扩充阅读

开发64位的.NET应用程序

在.NET平台之上,软件工程师在开发时一般不需要考虑开发的软件是32位还是64位的,因为Visual Studio提供了方便的手段为同样的.NET程序代码生成32位或64位的“中间语言(Intermediate Language,IL)”指令。

图1-2 生成32/64位的.NET应用程序

如图1-2所示,在Visual Studio项目属性页的“生成(Build)”选项卡中可以选择特定的软件运行平台,有以下几个选项:

  • Any CPU:生成不依赖于特定平台的IL指令代码。当.NET应用程序运行时,依据真实CPU的类型由“JIT(just-in-time,即时)编译器”编译为相应的机器码。这就是说,生成的程序集可以在32位或64位的计算机系统中执行。
  • x86:生成32位的IL指令代码(将运行于Intel x86兼容处理器之上)。如果在64位的计算机系统中运行,要求此系统支持32位仿真功能。
  • x64:生成64位IL指令代码,只能在装备有AMD/Intel X64类型CPU的计算机系统上执行。
  • Itanium:生成的IL指令代码仅能在Intel的Itanium(译为“安腾”)CPU上执行。安腾CPU一般用于高端应用,64位。

随着现代软件技术的发展,操作系统功能与结构变得越来越复杂,再以函数形式提供对操作系统功能的访问,函数的数量会有一个较快的增长,而函数数目的增加,必然会使其维护成本与开发难度迅速上升。

在软件发展史上,面向对象取代结构化编程技术成为主流是一次革命性的飞跃,但在Windows操作系统发展史上,Win32 API还带着深深的结构化编程时代的烙印。随着面向对象技术的成熟,从应用层软件开发的角度来看,操作系统越来越具有面向对象的特性,以面向对象的方式封装操作系统功能成为一个自然的选择。

从开发各种应用软件的程序员角度来看,.NET Framework可看成 Win32 API的一个替代品,它用易于理解与使用的面向对象方式调用Windows操作系统所提供的各种系统功能。在.NET Framework下编程,不再需要与各种复杂的Win32 API函数打交道,只需使用现成的组织得井井有条的各种“类(class)”即可,软件开发的门槛得到了有效的降低。

图1-3 .NET Framework的地位

图1-3展示了.NET Framework在整个软件体系结构中的地位。

如图1-3所示,.NET Framework成为了承上启下的一层,向内包容着操作系统内核,向外给运行于其上的各种.NET应用程序提供访问操作系统核心功能的服务。

从Windows 2003 Server开始,所有后续版本的Windows都集成了.NET Framework。

1.1.3 CLR与.NET基类库

“公共语言运行时(Common Language Runtime,CLR)”是.NET Framework的核心与基石。所有可以在.NET平台上运行的程序其实都处于CLR的管理之下。

从开发.NET应用程序角度,我们可以把CLR看成一台专用于运行.NET应用程序的“虚拟计算机(Virtual Machine,VM)”。

提示

本书在后面多处地方会使用到CLR这一术语指代.NET虚拟机。

CLR这台虚拟计算机所配备的“CPU”可以执行一种专有的指令——“IL(Intermediate Language,中间语言)指令”,这种指令相当地“高级”,拥有许多面向对象的特性,比如它的“.ctor”指令可以直接调用特定类型的构造函数,因此,我们不妨将其视为一种“面向对象的汇编语言”。

交叉链接

本书附录有一个《IL精简教程》,在本书许多章节中读者都可以看到IL代码的踪影。因此建议读者事先看一看这个教程。

有趣的是,这台虚拟计算机的体系结构相当简单,除了“CPU”之外,只有一个“计算堆栈(Evaluation Stack)”和相应的“内存”,数据就在这两个地方来回传送。

CLR可以看成是一台“基于堆栈”的虚拟计算机,它提供了即时编译、垃圾收集、类型管理、异常捕获等功能,为所有.NET应用程序提供一个运行环境。

尽管CLR的内部机理相当复杂,但如果希望能成为一名优秀的.NET软件工程师,还是需要对CLR的基本运行原理有一定的了解,为此,本书在介绍各种具体的.NET面向对象编程知识的同时,穿插介绍CLR技术内幕,期望这些内容能帮助读者不断地加深对CLR的了解,在.NET开发领域中游刃有余。

扩充阅读

.NET 4.0的“In-Process Side-by-Side Execution”特性

微软一开始设计.NET时就考虑到了版本问题,允许在同一台计算机上安装多个.NET版本,彼此互不干涉。但后来在实际开发中出现了新情况。比如使用.NET为某个应用程序开发了插件,而这些插件由于开发的时间不一样,有的运行于老版本的CLR之上,有的运行于新版本的CLR之上,这就给使用插件的宿主应用程序出了难题:是启动新版本的CLR还是启动老版本的CLR?不管启动哪个版本的CLR,原先不在这个版本上开发的插件都可能运行不正常。

为了解决这个问题,.NET 4.0引入了一个称为“In-Process Side-by-Side Execution(进程内的‘肩并肩’执行)”特性,允许在一个进程内同时启动不同版本的CLR。这样一来,插件宿主程序就可以为每个插件提供一个最合适的运行环境了。

一个典型的实例是安装.NET 4.0之后,IIS可以同时支持ASP.NET 2.0和4.0网站(见图1-4)。

需要指出的是,“In-Process Side-by-Side Execution”特性是.NET 4.0才提供的(当然以后的.NET 5.0或更新版本肯定会有),因此当前只能让.NET 4.0和其他老版本的CLR在同一个进程内“和平共处”,并不支持.NET 4.0之前的各版本CLR运行于同一进程之内,比如某插件宿主程序不能在同一个进程内同时启动.NET 2.0和.NET 3.5。

图1-4 IIS7中同时支持ASP.NET 2.0和4.0

正如C语言有C标准库一样,.NET为所有运行在CLR之上的应用程序提供了一个功能强大的公用代码库,完全按照面向对象的思想进行设计,几乎封装了操作系统的所有对外编程接口,而且这种类库是针对.NET平台而非特定的编程语言的,这就使得使用Visual Basic.NET、C#和C++等.NET编程语言的程序员能以一致的方式编程,大大方便了不同语言所编写代码之间的集成。

.NET Framework类库是.NET各项技术的“载体”,我们的.NET技术探索之旅,就体现为对.NET Framework类库中各个组件的了解、剖析和应用之上。