C#语言一直在进化、演变,使用这门语言的开发者社区也是如此。越来越多的程序员都选用C#作为自己在职业生涯中首次接触的语言,他们不会受到其他语言的影响。反之,有些开发者是先使用了几年以C语言为基础的其他语言,然后才转向C#的,这些开发者可能会受到早前那门语言的影响。然而,无论是始终使用C#的人,还是从其他语言转过来的人,都需要培养很多新的习惯,以适应C#语言近年来的变化。编译器开源之后,C#的创新速度大增,准备添加到语言中的新特性也会交给整个开发者社区来评审,而不像原来那样只由少数语言专家评审。此外,开发者社区还可以参与新特性的设计工作。
架构与部署方面的变化也要求C#开发者改变早前的编程习惯。拼装微服务(microservice)、构建分布式程序、分离算法与数据等做法,在当前的应用程序开发工作中已经很常见了。因此,C#语言也开始针对这些开发习惯做出调整。
笔者在安排本书第2版的内容时,考虑到了语言及开发者社区这两个方面的变化。本书不打算陈述语言的演变历史,而是着重讲解怎样用好当前的C#语言。与上一版相比,新版把那些与当前C#语言以及当前应用开发工作无关的内容都删掉了。新增的条目涵盖了语言与框架的新特性,以及众多开发者在用C#打造软件产品的过程中总结出来的经验。看过旧版 Effective C# 书系的读者稍后会发现,之前版本的《Effective C#》中有很多条目移到了这一版的《More Effective C#》中,此外,笔者还删除了旧版的许多条目。新版《Effective C#》与《More Effective C#》的内容是重新编排过的。本书收录的 50 条建议可以帮助你更高效地使用C#语言,从而成为更加专业的开发者。
本书假设你是使用C# 7来开发程序的,然而笔者并不会详细地讲到这一版C#语言所具备的每一种新特性。与 Effective 软件开发书系的其他作品类似,本书关注的也是怎样运用语言特性来解决日常工作中的实际问题。C# 7 中有一些新特性,可以实现出比旧式做法更为高效的新方案,本书尤其关注这些特性。大家在网上找到的某些解决办法可能是几年前的旧方案,针对这种情况,笔者会专门指出用新特性实现出的方案为什么比早前的那些办法要好。
你可以用基于Roslyn的分析器(analyzer)和代码修复程序(code fix)来判断某段 C# 代码有没有遵循书中所提到的某些建议。笔者把相关资源放在了 https://github.com/BillWagner/MoreEffectiveCSharpAnalyzers上。如果你有任何想法,或是打算给这份代码库提供新的内容,请点击该网页上的issue或pull request。
目标读者
本书适合以C#为首选编程语言的专业开发者阅读。你应该熟悉 C# 语言的写法及各项特性,并且能够熟练地运用 C# 语言的一般功能。书中不会再教你如何利用这些特性,而是要告诉你怎样把当前这一版 C# 语言所具备的特性正确地运用于日常开发工作中。
除了要熟悉C#本身的特性外,你还应该了解CLR(Common Language Runtime,公共语言运行时)与JIT(Just-In-Time,即时)编译器。
每章概述
当今世界,数据无处不在,但对待数据的方式却各有不同。面向对象的编程范式把数据与代码都当成类型及其职责的一部分。函数式的编程范式将方法视为数据。面向服务的编程范式则把数据与操纵数据的代码分隔开来。C#语言在演变的过程中把这些编程范式用到的习惯写法全都包括了进来,这就要求开发者在选择设计方式时必须多加考虑。第1章会告诉你怎样根据不同的编程范式来选用合适的写法。
编写程序在很大程度上是在设计API。使用API的人可以通过API看出API的设计者所规划的用法,还可以看出设计者是怎样理解其他开发者的需求和期望的。第 2 章介绍如何利用C#语言的众多特性来准确表达自己的设计思路,例如,怎样利用惰性初始化机制,怎样创建易于拼接的接口,以及怎样避免公有接口中的各种语言特性给人们带来困惑,等等。
基于任务的异步编程要求开发者采用一些新的写法,把这些基本的异步单元组合成完整的应用程序。掌握这些异步特性,有助于创建良好的异步操作 API,这些 API 要能够准确地反映出代码的执行方式,从而令调用者使用起来更加顺畅。第3章讲解怎样使用C#语言中基于任务的异步特性来创建合适的 API,以便准确地告诉调用方这个API会如何利用各种服务及资源。
第4章专门讲解异步编程中的一个领域:多线程并行执行。你会看到怎样利用PLINQ方便地拆解复杂的算法,从而令其能够运行在多个处理器核心及多个CPU上。
第5章讨论怎样把C#当成动态语言来使用。C#本身是强类型的静态类型语言,然而当今很多程序都在同时运用动态类型与静态类型这两种机制。C#一方面可以继续发挥静态类型的优势,另一方面又允许开发者在程序中同时运用动态编程的一些写法。第5章会讲解如何使用这些动态特性,以及怎样避免动态类型在整个程序中过于泛滥。
第6章会提出一些建议,告诉你怎样更好地与全世界的 C# 开发者交流。你可以通过各种办法为C#语言的发展做出贡献,并帮助大家把这门日常语言打造得更加优秀。
代码约定
在书中展示代码需要兼顾版面与清晰度。笔者尽量将范例代码写得较为精简,使其能够专注于该段代码所要讲解的问题,这就意味着类或方法中与本问题无关的部分可能会省略,而且错误恢复代码可能也不会写出,以求节省篇幅。公有方法应该验证调用方所传入的参数及其他输入数据,不过,由于篇幅的限制,这些内容同样会省略。此外,复杂的算法通常会对方法调用做出验证并编写try/finally结构,这些内容也会因篇幅过大而被略去。
笔者假设你能够从代码中看出它用到的几个常见命名空间。你可以认为每段范例代码都采用了下面几条using语句:
提供反馈
笔者尽量保证书中的文字与代码准确,这些内容也经过了其他人审阅,然而其中或许还是会有一些错误。如果你发现了错误,那么请发送邮件到
[email protected],或通过 Twitter 号 @billwagner 联系我。本书的勘误表发布在http://thebillwagner.com/Resources/More EffectiveCS上。书中有很多条目都是笔者通过电子邮件或 Twitter 与其他 C# 开发者讨论时想出来的。如果对这些条目所给出的建议有想法或评论,也请联系我。更一般的话题则可以在博客http://thebillwagner.com/blog上讨论。
致谢
本书能够写成,得益于很多朋友所提供的帮助。这些年来,笔者有幸结识了很多优秀的C#开发者。C# Insiders邮件列表中的每个人(无论是否在Microsoft公司)都提供了见解,并跟我交流,让我能把这本书写得更好。
其中,有几位C#开发者不仅直接提供了思路,而且还帮我把这些思路落实成具体的条目。感谢Jon Skeet、Dustin Campbell、Kevin Pilch、Jared Parsons、Scott Allen 与我讨论本书内容,尤其要多谢 Mads Torgersen,这一版中有很多新的想法都源自他的见解。
这一版的技术评审团队也很棒。Jason Bock、Mark Michaelis 与 Eric Lippert 认真检查了书里的文字和范例,使得本书质量大幅提高。他们细致而详尽的态度令笔者特别佩服。此外,他们还给出了一些建议,使我能把书中的许多话题解释得更加清楚。
与Addison-Wesley团队共事相当愉快。Trina Macdonald 是位出色的编辑与督导,是她敦促我写成这本书。Mark Renfrow 与 Olivia Basegio 极力支持 Trina 的编辑工作,他们也给我提供了许多帮助,以确保整份书稿都包含高品质的内容。Curt Johnson 依然很好地完成了本书的营销工作,无论你现在读到的是哪种格式,都离不开他的努力。
本书能够收录在 Scott Meyers 的 Effective 书系中,笔者深感荣幸。他读过每一本书稿,并提出了修改意见。Scott 是一位水平高超、经验丰富的软件开发者,他虽然不做 C#,但却能在书稿中发现那些解释得不够清楚、论证得不够充分之处。他为这一版所提供的建议与早前一样,都十分宝贵。
最后,感谢家人给我留出时间,让我能够写完本书。妻子 Marlene 总是能耐心地等我把文字或范例代码安排好。我能够写出包括本书在内的许多作品,并且写得如此顺畅,全靠她支持。