《.NET设计规范:约定、惯用法与模式》(第2版) 中文版序NET框架一推出,我就立即对它着了迷。这种技术让CLR( Common Language runtime,公共语言运行库)及其大量API以及C#语言的优势立刻彰显无遗。这些技术无不体现了API的通用设计风格和始终贯彻的一系列约定。这就是NET文化。一旦你了解了这种文化,就容易把有关知识运用到框架设计的其他领域中去。过去16年里,我一直在从事开源软件工作。由于开源的特点,开发者不仅文化背景不同,连开发时间也会跨越好几年,这时坚守种风格和编码约定就显得特别重要。虽然我们有维护人员,其日常的工作就是重写或修改提交来的软件,保证代码遵守项目编码标准和风格,但是,如果参与软件项目的所有人一开始就使用项目的约定,当然就更为理想。通过实践和标准所传达出的信息越多,未来新加入的人员就越容易上手。这有利于项目汇聚和融合新老代码。NET框架在成长,其开发者社区也在成长,人们不断地确定新的实践、模式和约定。Brad和 Krzysztof挺身而出,成为了这些规则的“监护人”,他们把这些新知识转变为现在这本规范。他们通常会在博客里介绍新的约定,收集社区的反馈,再记录下这些规范。在我看来,任何人若有兴趣用好NET框架就必须要常看他们的博客。这本书第1版出版以后,立即成为整个Mono社区传诵的经典,其原因大体有两个。首先我们可以由此了解各种 NET AP实现的原委和方式;其次,我们视其为无价的规范,努力将其贯彻在自己的程序和库的设计过程中。第2版不仅继承了第1版的成功之处,而且还添加了不少新的知识。许多规范还增加了注解,注解者本身就是行业里首屈一指的NET架构师和伟大的程序员,正是他们帮助确定了这些规范。最后我要说,这本书远不止是一本规范。它是我们热爱的一部经典,可以帮助我们成为名杰出的程序员,而这样的程序员在我们行业里现在还为数不多。Miguel de Icaza墨西哥自由软件开发者, GNOME和Mono项目创建者于马萨诸塞州波士顿市第一版序在NET框架开发的早期(那时甚至NET框架这个名字还没有诞生呢),我花了无数时间与各开发组一起对框架的设计进行评审,以确保最终得到的平台是易于理解、内在一致的。我始终认为对框架来说,最关键的品质应该是一致性。一旦用户理解了框架的一部分,那么就应该能立即理解框架的其他部分。可以想象,一大群聪明人在一起肯定会有许多不同意见,我们的开发组正是如此——再没有其他什么事情能比编码约定更能激发出生动而热烈的辩论了。但是,为了保证一致性,我们逐渐化解了各种不同意见,并将结果编纂为一组通用的规范,这样程序员就能容易地理解并使用框架Brad abrams和 Krzysztof Cwalina先后帮助我们把这些规范整理到文档中,并不断对其进行更新和完善。本书就是他们的工作成果这些规范有效地帮助我们完成了NET框架的三个版本和许多小项目。而且,这些规范还在指导着微软 Windows操作系统的下一代 API-winFX的开发。希望通过阅读本书,读者也能使自己的框架、类库及组件变得易于理解,易于使用希望框架设计能给你带来快乐。祝好运!Anders Hejlsberg微软杰出工程师,C#和 Delphi之父2005年6月于美国华盛顿州雷德蒙德市第二版译序从 Framework Design guidelines的第一版出版到现在,转眼间已经过去了四年。四年前,NET框架2.0和Ⅴ isual studio2005刚刚发布。之后我们先后迎来了NET框架30、NET框架3.5和Visual studio2008,而现在我们又即将迎来NET框架40和 Visual studio2010。事实上,在我忙于翻译本书的时候,也正是我忙于 Visual studio2010的开发和收尾工作的时候。本书保留了第一版中的大部分内容,对原有内容进行了适当的更新。这充分证明了书中的设计规范是经得起时间考验的,而这也正是它的核心价值所在。除此之外,本书还增加了许多新的内容,包括序列化、LINQ、依赖属性等等,从而涵盖了NET框架3.0和NET框架3.5中的核心特性。在过去的四年中,无论是我对技术的理解还是对语言的把握,都有了相当的提高,这一点将在书中得以体现。第一版的读者可能会发现中文第二版不仅更新了英文版中更新的那些部分,同时还对第一版已有的内容进行了修订和润色。我相信本书不仅是《NET设计规范(第2版)》,而且是一本更好的《NET设计规范》虽然我竭尽所能力求译文的准确和流畅,但鉴于时间和精力有限,难免会有翻译不当甚至是错误之处。为此我建立了一份网上勘误表,如果读者发现任何错误,都请通过该网页与我联系,旦确认我会立即将其更新到勘误表中。劫误表的网址为:www.gesoftfactory.com/ge/FrameworkDesign Guidelines2/。我要感谢本书的编辑丁晓昀对我的理解和支持,我们之间的合作非常愉快。我还要感谢我的同事吴宇进、田超、唐友、张羿和王彩霞,他们在繁忙的工作之余审阅译稿,发现了不少难以觉察的问题,并提出了许多宝贵的意见和建议,从而使得本书的质量更上一层楼。最后,我要感谢我的妻儿,他们的支持和鼓励,是我前进的动力。葛子昂2010年3月前言本书介绍了设计框架的最佳实践。所谓框架,即可重用面向对象程序库。书中所描述的规范普遍适用于下述规模不同、可重用程度不同的框架。口大规模的系统框架。这些框架通常都有成千上万个类型,并且为大量的开发人员所使用,如NET框架口中等规模的程序库。这既可以是大型分布式应用程序的可重用层,也可以是对系统框架的可重用扩展,如web服务扩展( Web Services Enhancement)日小规模组件。为多个应用程序所共享,如网格控件( grid control)库。值得注意的是,本书关注的是直接影响框架(可以公开访问的API①)可编程能力的设计问题。因此,我们不会过多涉及实现细节。正如一本介绍用户界面设计的书不会讨论有关如何实现碰撞测试( hit testing)的细节一样,本书也不会讲解如何实现二叉排序。这样的定位使我们能够提供针对框架设计师的完整可靠的指南,而不是又一本关于编程方面的书。书中的规范是在NET框架的开发早期形成的,它们最早只是少量的命名和设计约定,但是经过不断改进、检验、提炼,这些规范最终成为了微软内部公认的框架设计规范。这些规范历经NET框架三个版本的长期开发,凝聚了数千名开发人员累积的经验和智慧。我们并不希望本书只是基于一些理想化的设计理念,我们认为本书是极其注重实效的,微软的各开发组将之用于日常开发就是很好的证明本书包含许多评注,它们有的评注了相应规范的利弊权衡,有的介绍了其历史,有的给出了进一步的说明,有的提出了自己的批评意见。所有评注都来自经验丰富的框架设计师、业界专家及用户。这些源于开发一线的故事,为书中的许多规范增色不少。为了使命名空间名、类、接口、方法、属性及类型能够在正文中一目了然,我们用 Courier字体表示。①包括一些公共类型,和这些类型的公有、受保护的和显式实现的成员。前言本书的读者应该基本知道如何使用NET框架编程,有一些规范要求读者熟悉NET框架3.5版引入的新特性。如果你想找一本介绍框架编程的书,那么可以参考书后的推荐读物,其中有些非常好的建议。规范的表示方法我们通过要(Do)、考虑( Consider)、避免( Avoid)、不要( Do not)这些词把书中的规范组织成一条条简单的建议。每一条规范都描述了一种好的或是不好的做法,并用统一的方式来表示。好的做法,在其前面会用√表示;与此对应,不好的做法则用k表示。每一条规范的措词也会明确表示出这条规范的重要性。例如,“要…”描述的是必须遵循的规范(下面所有的例子都摘自本书)√Do要在命名自定义的 attribute类时加上“ Attribute”后缀。public class obsoleteAttribute Attribute ..另一方面,“考虑……”描述的是在一般情况下应该遵循的规范,但如果完全理解规范背后的道理,并有很好的理由不遵循它时,也不要畏惧打破常规。CONSIDER考虑将类型定义为结构,而不要定义为类,前提是该类型的实例较小、存活期较短或通常内嵌在其他对象中。同样,“不要…”描述的是一些绝对不应该违反的规范。κ DO NOT不要把可变类型的实例赋给只读字段避免…”就没有那么绝对,它描述的做法虽然通常并不好,但却存在一些已知的可以违反该规范的情况。AVoD避免使用ICo11 ection或ICo1 ection作为参数,前提是其目的仅仅只是为了访问 Count属性。对那些更为复杂的规范,我们会另外提供一些背景知识、代码示例及基本原理。√/Do要为值类型实现 IEquatab1e。值类型的 Object,Equa1s方法会导致装箱,而且由于使用了反射,因此默认实现的效率不高。 IEquatab1e<> Equals能够提供更好的性能,而且它的实现可以避免装箱操作。①“必须”这一措词可能有点太强。虽然有些规范我们的确应该始终遵守,但此类规范极其罕见。另一方面,在些非常特殊的情况下,你可能需要违反一些“要…”规范,而框架的用户仍能从中受益前言xilpublic struct Int32 IEquatable(ub1icb。o1Eua1s(工nt32 other){.}语言选择和样例代码CLR的目标之一就是支持多种编程语言,这其中既包括微软提供的语言,如C++、VB、C#、F#、 Python和Ruby,也包括第三方语言,如Eifl、 COBOL和 Fortran等。因此,本书适用于开发和使用现代框架的多种语言。为了加强多语言框架设计的概念,我们曾考虑过使用几种不同的编程语言来编写样例代码但最终我们还是放弃了这种想法,因为使用不同的语言虽然有助于理念的表达,但这样做可能会迫使读者学习好几种新语言,而这并不是本书的目的。我们决定使用一种易于为广大开发人员阅读的语言,最终选择了C#,因为C#是一种简单的语言,它源自C语言家族—个在框架开发方面有着悠久历史的家族(C语言家族中的其他语言包括C、C++、Java和C#)。语言的选择对于许多程序员来说至关重要,对那些不适应C#的读者,我们谨在此表示歉意。关于本书本书提供了自上向下的框架设计规范。口第1章简要介绍了本书,讨论了框架设计的理念,这是书中唯一没有规范的章口第2章为框架的总体设计提供了基本的原则和规范。第3章包含了常用设计惯用法以及为命名空间、类型、成员等框架各部分命名的规范口第4章为类型设计提供了规范第5章为类型成员的设计提供了进一步的规范口第6章讨论了一些对保证框架的扩展性来说至关重要的问题和规范。口第7章为与异常有关的工作提供了规范,及推荐使用的错误报告机制。口第8章为扩展和使用框架中的常用类型提供了规范口第9章为框架中常用的设计模式提供了规范和示例。口附录A对本书使用的编程约定做了简要的描述。口附录B介绍了 FxCop工具。可以用该工具来分析框架的二进制文件,以验证框架是否符合本书所描述的规范。本书的附带光盘中包括了此工具口附录C是一份AP规范样例,这些规范通常是微软公司的框架设计人员在设计API时创建的本书附带光盘还包括了另一份AP规范样例和其他有用的资源。致谢本书实质上是对数千人智慧结晶的一个汇总,对所有这些人我们深表谢意。微软公司的许多人在过去几年中长期努力地工作,是他们提出建议,进行辩论,并最终撰写了书中的许多规范。虽然不可能列出所有的参与者,但在此我们要特别感谢: Chris anderson、Erik Christensen、 Jason clark、 Joe duffy、 Patrick dussud、 Anders Hejlsberg、 Jim millerMichael Murray、 Lance olson、 Eric Gunnerson、 Dare Obasanjo、 Steve Starck、 Kit george、MikeHillberg、 Greg Schecter、 Mark boulter、 Asad Jawahar、 Justin van patten和 Mircea trofin许多人审阅了本书并提供了评注,我们在此同样表示感谢: Mark alcazar、 Chris andersonChristopher brumme、 Pablo castro、 Jason Clark、 Steven Clarke、 Joe Duffy、 Patrick dussud、Mike Fanning、 Kit George、 Jan gray、 Brian Grunkemeyer、 Eric Gunnerson、 Phil haack、 AndersHejlsberg、 David kean、 Rico mariani、 Anthony Moore、 Vance Morrison、 Christophe NasarreDare Obasanjo、 Brian Pepin、 Jon Pincus、 Jeff prosise、 Brent Rector、 Jeffrey richter、GregSchechter、 Chris sells, Steve Starck、 Herb Sutter. Clemens Szyperski、 Mircea Trofin和PaulVick上述同仁对本书做了非常必要的补充增益。他们为正文添加了注解内容,补充了有关历史背景知识,让文风变得风趣生动,这些都十分出彩,令本书增色不少附录B对 FxCop的介绍实际上是 Sheridan harrison和 Dayid Kean编写的,在此我们对他们表示感谢。感谢 Martin Heller,他从技术上、精神上给我们以帮助和支持。感谢 Pierre nallet、 GeorgeByrkit、 Christof falk、 Paul Besley、 Bill Wagner和 Peter winkler,他们提出了中肯而有益的意见。特别感谢 Susann Ragsdale,是她把诸多不甚连续的想法化为本书。她耐心、极具幽默感,她的创作思路完美无瑕,所有这些使得本书的写作过程变得格外轻松。关于评注者Mark alcazar曾经想成为一名著名的运动员。但是,当发现自己没有很好的手眼协调性和体育天赋时,他转向了计算机行业。在过去九年中,Mark一直都在微软公司工作。他从事过Internet Explorer中HTML渲染引擎的开发,他还是 Windows Presentation Foundation开发组的一员,从头到尾参与了 Windows Presentation Foundation的开发。Mark热衷于让空白区域保持致,喜欢喝 Talking Rain的桃子和油桃口味饮料,还喜欢吃辛辣的食物。他拥有西印度大学的学士学位和宾夕法尼亚大学的硕士学位。Chris Anderson是微软公司互联系统部门的一名架构师。 Chris主要关注那些用来实现下一代应用程序和服务的NET技术,以及相关的设计和架构。从2002年开始到不久以前,他都一直是WPF开发组的主管架构师。 Chris曾经撰写过许多文章和白皮书,他不仅在全球的许多大会(包括 Microsoft Professional Developers Conference、 Microsoft teched、 WinDev、 Dev con等等)做过演讲,而且还做过许多主题演讲。他在www.simplegeek.com中的博客也广受欢迎Christopher Brumme于1997年加入微软公司,那时CLR开发组还正在筹建的过程中。此后,他广泛参与了CLR的设计,还参与了其中执行引擎部分的实现。目前他正在关注托管代码中的并发问题。在加入CLR开发组之前, Chris曾先后在 Borland和 Oracle公司担任架构师。Pablo Castro是 SQL Server开发组的技术主管。在 SQL Server和NET框架中的许多领域,他都做出了诸多贡献。其中包括 SQL-CLR集成、类型系统的扩展性、TDS客户服务器协议,以及 ADO NET API。 Pablo目前正在从事 ADO.NET实体框架( Entity Framework)的开发。除此之外,他还领导着 ADO NET数据服务( Data services)项目的开发,该项目寻求的是一种将数据和Web技术集成起来的方法。在加入微软公司之前,Pabo在许多公司从事过各种软件的开发,其中包括用于信用卡评估和风险分析的分布式推理系统、协作软件,以及群件( groupware)。Jason Clark是微软公司的一名软件架构师。他在微软公司的软件开发生涯包括三个版本的 Windows、三个版本的NET框架,以及WCF。在2000年他出版了他的第一本关于软件开发的书。他还一直参与各种杂志和其他出版物的工作。他目前负责 Visual studio的数据库版本。除了软件开发之外, Jason最热爱的就是他的妻子和孩子们,他们一家幸福地生活在西雅图地区。Steven Clarke自从1999年开始就在微软的开发者部门担任用户体验研究员。他主要的兴趣