猜你喜欢
More Effective C#:改善C#代码的50个有效方法(原书第2版)

More Effective C#:改善C#代码的50个有效方法(原书第2版)

书籍作者:比尔·瓦格纳 ISBN:9787111620716
书籍语言:简体中文 连载状态:全集
电子书格式:pdf,txt,epub,mobi,azw3 下载次数:9069
创建日期:2021-02-14 发布日期:2021-02-14
运行环境:PC/Windows/Linux/Mac/IOS/iPhone/iPad/Kindle/Android/安卓/平板
内容简介
在本书中,世界的.NET专家Bill Wagner介绍了用于写出健壮且容易完成的C# 7.0代码的50条中阶至高阶技巧,反映了C#语言及其开发社区的发展,可帮助读者解决每日编程工作中可能遇到的问题。
前言
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 总是能耐心地等我把文字或范例代码安排好。我能够写出包括本书在内的许多作品,并且写得如此顺畅,全靠她支持。
目录
译者序
前言
第1章 处理各种类型的数据 / 1
第1条:使用属性而不是可直接访问的数据成员 / 1
第2条:尽量采用隐式属性来表示可变的数据 / 7
第3条:尽量把值类型设计成不可变的类型 / 11
第4条:注意值类型与引用类型之间的区别 / 16
第5条:确保 0 可以当成值类型的有效状态使用 / 21
第6条:确保属性能够像数据那样运用 / 25
第7条:用元组来限制类型的作用范围 / 30
第8条:在匿名类型中定义局部函数 / 35
第9条:理解相等的不同概念及它们之间的关系 / 40
第10条:留意GetHashCode()方法的使用陷阱 / 49
第2章 API设计 / 57
第11条:不要在API中提供转换运算符 / 57
第12条:尽量用可选参数来取代方法重载 / 61
第13条:尽量缩减类型的可见范围 / 65
第14条:优先考虑定义并实现接口,而不是继承 / 69
第15条:理解接口方法与虚方法之间的区别 / 77
第16条:用Event模式来实现通知功能 / 82
第17条:不要把类的内部对象通过引用返回给外界 / 87
第18条:优先考虑重写相关的方法,而不是创建事件处理程序 / 91
第19条:不要重载基类中定义的方法 / 94
第20条:了解事件机制为何会提升对象在运行期的耦合程度 / 98
第21条:不要把事件声明成virtual / 100
第22条:尽量把重载方法创建得清晰、简洁而完备 / 106
第23条:让 partial类的构造函数、mutator方法和事件处理程序调用适当的partial方法 / 112
第24条:尽量不要实现ICloneable接口,以便留出更多的设计空间 / 117
第25条:数组类型的参数应该用params加以修饰 / 122
第26条:在迭代器与异步方法中定义局部函数,以便尽早地报错 / 126
第3章 基于任务的异步编程 / 131
第27条:使用异步方法执行异步工作 / 131
第28条:不要编写返回值类型为void的异步方法 / 136
第29条:不要把同步方法与异步方法组合起来使用 / 141
第30条:使用异步方法以避免线程分配和上下文切换 / 146
第31条:避免不必要的上下文编组 / 147
第32条:通过Task对象来安排异步工作 / 151
第33条:考虑实现任务取消协议 / 157
第34条:缓存泛型异步方法的返回值 / 164
第4章 并行处理 / 167
第35条:了解PLINQ是怎样实现并行算法的 / 167
第36条:编写并行算法时要考虑异常状况 / 179
第37条:优先使用线程池而不是创建新的线程 / 185
第38条:考虑使用BackgroundWorker在线程之间通信 / 190
第39条:学会在XAML环境下执行跨线程调用 / 194
第40条:首先考虑用lock()实现同步 / 202
第41条:尽量缩减锁定范围 / 209
第42条:不要在加了锁的区域内调用未知的方法 / 212
第5章 动态编程 / 217
第43条:了解动态编程的优点及缺点 / 217
第44条:通过动态编程技术更好地运用泛型参数的运行期类型 / 226
第45条:使用DynamicObject和IDynamicMetaObjectProvider实现数据驱动的动态类型 / 229
第46条:学会正确使用Expression API / 240
第47条:尽量减少公有API中的动态对象 / 246
第6章 加入全球C#社区 / 253
第48条:最流行的写法不一定最合适 / 253
第49条:与大家一起制定规范并编写代码 / 255
第50条:考虑用分析器自动检查代码质量 / 256
中英文词汇对照表 / 258
产品特色