计算机书籍控

深入理解C#(第2版)

   《深入理解C#(第2版)》是世界顶级技术专家“十年磨一剑”的经典之作,在C#和.NET领域享有盛誉。与其他泛泛介绍C#的书籍不同,本书深度探究C#的特性,并结合技术发展,引领读者深入C#的时空。作者Jon Skeet从语言设计的动机出发,介绍支持这些特性的核心概念。作者将新的语言特性放在C#语言发展的背景之上,用极富实际意义的示例,向读者展示编写代码和设计解决方案的最佳方式。同时作者将多年的C#开发经验与读者分享,读者可咀其精华、免走弯路,使程序设计水平更上一层楼。    本书是对第1版的全新修订,更详尽地阐述了C#的核心概念,并全面介绍了C# 4的新特性和代码契约。C# 4功能异常强大,掌握本书讲解的泛型、Lambda表达式、动态类型、LINQ、迭代器块和其他新特性后。读者可以实现无数神奇的功能,在C#的世界中大展宏图。

目录


目 录

第一部分 基础知识

第1章 C#开发的进化史 2 1.1 从简单的数据类型开始 3 1.1.1 C# 1中定义的产品类型 3 1.1.2 C# 2中的强类型集合 4 1.1.3 C# 3中自动实现的属性 5 1.1.4 C# 4中的命名实参 6 1.2 排序和过滤 7 1.2.1 按名称对产品进行排序 7 1.2.2 查询集合 10 1.3 处理未知数据 11 1.3.1 表示未知的价格 12 1.3.2 可选参数和默认值 12 1.4 LINQ简介 13 1.4.1 查询表达式和进程内查询 13 1.4.2 查询XML 14 1.4.3 LINQ to SQL 15 1.5 COM和动态类型 16 1.5.1 简化COM互操作 16 1.5.2 与动态语言互操作 17 1.6 剖析.NET平台 18 1.6.1 C#语言 18 1.6.2 运行时 19 1.6.3 框架库 19 1.7 怎样写出超炫的代码 19 1.7.1 采用代码段形式的全能代码 20 1.7.2 教学代码不是产品代码 21 1.7.3 你的新朋友:语言规范 21 1.8 小结 21

第2章 C# 1所搭建的核心基础 23 2.1 委托 23 2.1.1 简单委托的构成 24 2.1.2 合并和删除委托 28 2.1.3 对事件的简单讨论 29 2.1.4 委托小结 30 2.2 类型系统的特征 31 2.2.1 C#在类型系统世界中的位置 31 2.2.2 C# 1的类型系统在什么时候不够用 34 2.2.3 类型系统特征总结 36 2.3 值类型和引用类型 36 2.3.1 现实世界中的值和引用 36 2.3.2 值类型和引用类型基础知识 37 2.3.3 走出误区 38 2.3.4 装箱和拆箱 40 2.3.5 值类型和引用类型小结 41 2.4 C# 1之外:构建于坚实基础之上的新特性 41 2.4.1 与委托有关的特性 41 2.4.2 与类型系统有关的特性 43 2.4.3 与值类型有关的特性 45 2.5 小结 46

第二部分 C# 2:解决C# 1的问题

第3章 用泛型实现参数化类型 48 3.1 为什么需要泛型 49 3.2 日常使用的简单泛型 50 3.2.1 通过例子来学习:泛型字典 50 3.2.2 泛型类型和类型参数 52 3.2.3 泛型方法和判读泛型声明 55 3.3 深化与提高 58 3.3.1 类型约束 58 3.3.2 泛型方法类型实参的类型推断 62 3.3.3 实现泛型 63 3.4 高级泛型 68 3.4.1 静态字段和静态构造函数 69 3.4.2 JIT编译器如何处理泛型 70 3.4.3 泛型迭代 72 3.4.4 反射和泛型 74 3.5 泛型在C#和其他语言中的限制 78 3.5.1 泛型可变性的缺乏 78 3.5.2 缺乏操作符约束或者“数值”约束 82 3.5.3 缺乏泛型属性、索引器和其他成员类型 83 3.5.4 同C++模板的对比 84 3.5.5 和Java泛型的对比 85 3.6 小结 86

第4章 可空类型 88 4.1 没有值时怎么办 88 4.1.1 为什么值类型的变量不能是null 89 4.1.2 在C# 1中表示空值的模式 89 4.2 System.Nullable和System.Nullable 91 4.2.1 Nullable简介 91 4.2.2 Nullable装箱和拆箱 94 4.2.3 Nullable实例的相等性 95 4.2.4 来自非泛型Nullable类的支持 96 4.3 C# 2为可空类型提供的语法糖 96 4.3.1 ?修饰符 97 4.3.2 使用null 进行赋值和比较 98 4.3.3 可空转换和操作符 99 4.3.4 可空逻辑 102 4.3.5 对可空类型使用as操作符 103 4.3.6 空合并操作符 104 4.4 可空类型的新奇用法 106 4.4.1 尝试一个不使用输出参数的操作 107 4.4.2 空合并操作符让比较不再痛苦 108 4.5 小结 111

第5章 进入快速通道的委托 112 5.1 向笨拙的委托语法说拜拜 113 5.2 方法组转换 114 5.3 协变性和逆变性 115 5.3.1 委托参数的逆变性 116 5.3.2 委托返回类型的协变性 117 5.3.3 不兼容的风险 118 5.4 使用匿名方法的内联委托操作 119 5.4.1 从简单的开始:处理一个参数 119 5.4.2 匿名方法的返回值 121 5.4.3 忽略委托参数 123 5.5 在匿名方法中捕捉变量 124 5.5.1 定义闭包和不同的变量类型 124 5.5.2 测试被捕获的变量的行为 126 5.5.3 捕获变量到底有什么用处 127 5.5.4 捕获变量的延长生存期 127 5.5.5 局部变量实例化 128 5.5.6 共享和非共享的变量混合使用 130 5.5.7 捕获变量的使用规则和小结 132 5.6 小结 133

第6章 实现迭代器的捷径 134 6.1 C# 1:手写迭代器的痛苦 135 6.2 C# 2:利用yield语句简化迭代器 137 6.2.1 迭代器块和yield return简介 137 6.2.2 观察迭代器的工作流程 139 6.2.3 进一步了解迭代器执行流程 141 6.2.4 具体实现中的奇特之处 144 6.3 真实的例子:迭代范围值 145 6.3.1 迭代时刻表中的日期 145 6.3.2 迭代文件中的行 146 6.3.3 使用迭代器块和谓词对项进行延迟筛选 148 6.4 使用CCR实现伪同步代码 150 6.5 小结 152

第7章 结束C# 2的讲解:最后的一些特性 153 7.1 分部类型 154 7.1.1 在多个文件中创建一个类型 154 7.1.2 分部类型的使用 156 7.1.3 C# 3独有的分部方法 157 7.2 静态类型 159 7.3 独立的取值方法/赋值方法属性访问器 161 7.4 命名空间别名 162 7.4.1 限定的命名空间别名 163 7.4.2 全局命名空间别名 164 7.4.3 外部别名 164 7.5 Pragma指令 166 7.5.1 警告pragma 166 7.5.2 校验和pragma 167 7.6 非安全代码中的固定大小的缓冲区 167 7.7 把内部成员暴露给选定的程序集 169 7.7.1 在简单情况下的友元程序集 169 7.7.2 为什么使用InternalsVisibleTo 170 7.7.3 InternalsVisibleTo和签名程序集 170 7.8 小结 171

第三部分 C# 3:革新写代码的方式

第8章 用智能的编译器来防错 174 8.1 自动实现的属性 175 8.2 隐式类型的局部变量 176 8.2.1 用var声明局部变量 177 8.2.2 隐式类型的限制 178 8.2.3 隐式类型的优缺点 179 8.2.4 建议 180 8.3 简化的初始化 180 8.3.1 定义示例类型 181 8.3.2 设置简单属性 182 8.3.3 为嵌入对象设置属性 183 8.3.4 集合初始化列表 184 8.3.5 初始化特性的应用 186 8.4 隐式类型的数组 187 8.5 匿名类型 188 8.5.1 第一次邂逅匿名类型 188 8.5.2 匿名类型的成员 190 8.5.3 投影初始化列表 191 8.5.4 重点何在 192 8.6 小结 193

第9章 Lambda表达式和表达式树 194 9.1 作为委托的Lambda表达式 195 9.1.1 准备工作:Func委托类型简介 195 9.1.2 第一次转换成Lambda表达式 196 9.1.3 用单一表达式作为主体 197 9.1.4 隐式类型的参数列表 197 9.1.5 单一参数的快捷语法 198 9.2 使用List和事件的简单例子 199 9.2.1 对列表进行筛选、排序并设置其他操作 199 9.2.2 在事件处理程序中进行记录 201 9.3 表达式树 202 9.3.1 在程序中构建表达式树 202 9.3.2 将表达式树编译成委托 204 9.3.3 将C# Lambda表达式转换成表达式树 205 9.3.4 位于LINQ核心的表达式树 208 9.3.5 LINQ之外的表达式树 209 9.4 类型推断和重载决策发生的改变 211 9.4.1 改变的起因:精简泛型方法调用 211 9.4.2 推断匿名函数的返回类型 212 9.4.3 分两个阶段进行的类型推断 213 9.4.4 选择正确的被重载的方法 217 9.4.5 类型推断和重载决策 218 9.5 小结 219

第10章 扩展方法 220 10.1 未引入扩展方法之前的状态 221 10.2 扩展方法的语法 223 10.2.1 声明扩展方法 223 10.2.2 调用扩展方法 224 10.2.3 扩展方法是怎样被发现的 225 10.2.4 在空引用上调用方法 226 10.3 .NET 3.5中的扩展方法 227 10.3.1 从Enumerable开始起步 228 10.3.2 用Where筛选并将方法调用链接到一起 229 10.3.3 插曲:似曾相识的Where方法 231 10.3.4 用Select方法和匿名类型进行投影 232 10.3.5 用OrderBy方法进行排序 232 10.3.6 涉及链接的实际例子 234 10.4 使用思路和原则 235 10.4.1 “扩展世界”和使接口更丰富 235 10.4.2 流畅接口 236 10.4.3 理智使用扩展方法 237 10.5 小结 238

第11章 查询表达式和LINQ to Objects 240 11.1 LINQ介绍 241 11.1.1 LINQ中的基础概念 241 11.1.2 定义示例数据模型 245 11.2 简单的开始:选择元素 246 11.2.1 以数据源作为开始,以选择作为结束 246 11.2.2 作为查询表达式基础的编译器转换 247 11.2.3 范围变量和重要的投影 249 11.2.4 Cast、OfType和显式类型的范围变量 251 11.3 对序列进行过滤和排序 252 11.3.1 使用where子句进行过滤 253 11.3.2 退化的查询表达式 253 11.3.3 使用orderby子句进行排序 254 11.4 let子句和透明标识符 256 11.4.1 用let来进行中间计算 256 11.4.2 透明标识符 257 11.5 联接 258 11.5.1 使用join子句的内联接 258 11.5.2 使用join into子句进行分组联接 262 11.5.3 使用多个from子句进行交叉联接和合并序列 264 11.6 分组和延续 267 11.6.1 使用group by子句进行分组 267 11.6.2 查询延续 270 11.7 在查询表达式和点标记之间作出选择 272 11.7.1 需要使用点标记的操作 273 11.7.2 选择点标记 273 11.7.3 选择查询表达式 274 11.8 小结 275

第12章 超越集合的LINQ 276 12.1 使用LINQ to SQL查询数据库 277 12.1.1 数据库和模型 277 12.1.2 用查询表达式访问数据库 279 12.1.3 包含联接的查询 281 12.2 用IQueryable和IQueryProvider进行转换 283 12.2.1 IQueryable和相关接口的介绍 283 12.2.2 模拟接口实现来记录调用 285 12.2.3 把表达式粘合在一起:Queryable的扩展方法 287 12.2.4 模拟实际运行的查询提供器 289 12.2.5 包装IQueryable 290 12.3 LINQ友好的API和LINQ to XML 290 12.3.1 LINQ to XML中的核心类型 290 12.3.2 声明式构造 292 12.3.3 查询单个节点 294 12.3.4 合并查询操作符 296 12.3.5 与LINQ和谐共处 297 12.4 用并行LINQ代替LINQ to Objects 297 12.4.1 在单线程中绘制曼德博罗特集 297 12.4.2 ParallelEnumerable、Parallel-Query和AsParallel 299 12.4.3 调整并行查询 300 12.5 使用LINQ to Rx反转查询模型 301 12.5.1 IObservable和IObserver 302 12.5.2 简单地开始 303 12.5.3 查询可观察对象 304 12.5.4 意义何在 306 12.6 扩展LINQ to Objects 306 12.6.1 设计和实现指南 307 12.6.2 示例扩展:选择随机元素 308 12.7 小结 309

第四部分 C# 4:良好的交互性

第13章 简化代码的微小修改 312 13.1 可选参数和命名实参 312 13.1.1 可选参数 313 13.1.2 命名实参 317 13.1.3 两者相结合 321 13.2 改善COM互操作性 324 13.2.1 在C# 4之前操纵Word是十分恐怖的 325 13.2.2 可选参数和命名实参的复仇 325 13.2.3 按值传递ref参数 326 13.2.4 调用命名索引器 327 13.2.5 链接主互操作程序集 328 13.3 接口和委托的泛型可变性 330 13.3.1 可变性的种类:协变性和逆变性 331 13.3.2 在接口中使用可变性 332 13.3.3 在委托中使用可变性 334 13.3.4 复杂情况 335 13.3.5 限制和说明 336 13.4 对锁和字段风格的事件的微小改变 339 13.4.1 健壮的锁 339 13.4.2 字段风格的事件 340 13.5 小结 341

第14章 静态语言中的动态绑定 342 14.1 何谓,何时,为何,如何 343 14.1.1 何谓动态类型 343 14.1.2 动态类型什么时候有用,为什么 344 14.1.3 C# 4如何提供动态类型 345 14.2 关于动态的快速指南 345 14.3 动态类型示例 348 14.3.1 COM和Office 348 14.3.2 动态语言 350 14.3.3 纯托管代码中的动态类型 353 14.4 幕后原理 358 14.4.1 DLR简介 358 14.4.2 DLR核心概念 360 14.4.3 C#编译器如何处理动态 362 14.4.4 更加智能的C#编译器 365 14.4.5 动态代码的约束 368 14.5 实现动态行为 370 14.5.1 使用ExpandoObject 370 14.5.2 使用DynamicObject 374 14.5.3 实现IDynamicMetaObject-Provider 380 14.6 小结 383

第15章 使用契约让代码更加清晰 385 15.1 未引入代码契约之前的状态 386 15.2 代码契约 387 15.2.1 前置条件 388 15.2.2 后置条件 389 15.2.3 固定条件 390 15.2.4 断言和假设 392 15.2.5 旧式契约 393 15.3 使用ccrewrite和ccrefgen重写二进制 394 15.3.1 简单重写 394 15.3.2 契约继承 395 15.3.3 契约引用程序集 398 15.3.4 失败行为 399 15.4 静态检查 401 15.4.1 开始静态检查 401 15.4.2 隐式职责 403 15.4.3 有选择性的检查 406 15.5 使用ccdocgen 将契约文档化 408 15.6 契约实战 410 15.6.1 契约中有什么 410 15.6.2 如何开始 411 15.6.3 无处不在的选项 412 15.7 小结 414

第16章 何去何从 415 16.1 C#——传统与现代的结合 415 16.2 计算机科学和.NET 416 16.3 计算机世界 417 16.4 再会 417

附录A LINQ标准查询操作符 419 附录B .NET中的泛型集合 430 附录C 版本总结 440

  </t></t></t></t></t></t></t></t>

书籍下载

免费下载 密码:esel

正版书籍

深入理解C#(第2版)