CLR关键章节。

打勾的是重点。没打勾的通读,不要直接跳过。标注页码或者被高亮的是必须重点读的。

第一章 CLR的执行模型

  • 1.1 将源代码编译成托管模块
    • 托管模块的组成(p5)
    • 元数据概述(p5)
  • 1.2 将托管模块合并成程序集
    • 程序集的概念 (p6-7)
  • 1.3 加载公共语言运行时
  • 1.4 执行程序集的代码
    • JITCompiler函数的功能 (p11)
    • IL概述(p15)
  • 1.5 本机代码生成器: NGen.exe
  • 1.6 Framework类库
    • 常规的FCL命名空间(p21)
  • 1.7 通用类型系统
    • 访问修饰符(p23)
  • 1.8 公共语言规范
    • C#、CLR/CTS、CLS的关系(p25)
    • Test类与其IL(p26-27)
  • 1.9 与非托管代码的互操作性

第二章 生成、打包、部署和管理应用程序及类型

  • 2.1 .NET Framework部署目标
  • 2.2 将类型生成到模块中(建议动手实践)
  • 2.3 元数据概述
    • 元数据的概念(p33)
    • 元数据的几张表(p34-35)
    • IL查看元数据(p35-38,建议动手实践)
  • 2.4 将模块合并成程序集
    • 程序集与清单(p39)
    • 清单元数据表(p41)
    • /addmodule与包含多个模块程序集的结构(p42-43,建议动手实践)
    • AL.exe(p45-47,建议动手实践)
  • 2.5 程序集版本资源信息
    • 版本号格式(p50)
  • 2.6 语言文化
    • 附属程序集的概念(p51)
  • 2.7 简单应用程序部署(私有部署的程序集)
  • 2.8 简单管理控制(配置)

第三章 共享程序集和强命名程序集

  • 3.1 两种程序集,两种部署
    • 弱命名程序集和强命名程序集的区别(p58)
  • 3.2 为程序集分配强名称
    • 强命名程序集的字符串标识结构(p59)
    • 签名的概念、过程(p59-63)
  • 3.3 全局程序集缓存
  • 3.4 在生成的程序集中引用强命名程序集
  • 3.5 强命名程序集能防篡改
  • 3.6 延迟签名
  • 3.7 私有部署强命名程序集
  • 3.8 “运行时”如何解析类型引用 (了解过程,对照p72的图)
  • 3.9 高级管理配置

第四章 类型基础

  • 4.1 所有类型都从System.Object派生
    • System.Object的几个方法(p81-82)
    • new操作符的工作(p82-83)
  • 4.2 类型转换
    • is和as的概念和区别
    • 类型安全性测验(p85代码,p86表格,建议动手实践)
  • 4.3 命名空间和程序集
    • 命名空间和程序集的关系(p89)
  • 4.4 运行时相互关系 (全部高能)

第五章 基元类型、引用类型和值类型

  • 5.1 编程语言的基元类型
    • C#基元类型与对应的FCL类型(p100表格)
    • checked和unchecked (p102-105,建议动手实践,查看IL)
  • 5.2 引用类型和值类型
    • 引用类型和值类型的概念与区别(p106-109)
    • CLR如何控制类型中的字段布局(p110)
  • 5.3 值类型的装箱和拆箱
    • 装箱的概念(p111)
    • 拆箱的概念(p112)
    • 一些例子(p113-123,建议动手实践,查看IL)
    • Equals与同一性(p123-126)
  • 5.4 对象哈希码
  • 5.5 dynamic基元类型
    • dynamic的概念、功能
    • dynamic与var的区别(p130)
    • dynamic与反射

第六章 类型和成员基础

  • 6.1 类型的各种成员
  • 6.2 类型的可见性
  • 6.3 成员的可访问性
  • 6.4 静态类
  • 6.5 分布类、结构和接口
  • 6.6 组件、多态和版本控制
    • C#关键字对版本控制的影响(p144表格)
    • CLR如何调用虚方法、属性和事件
      • call和callvirt的区别 (p145-147)

第七章 常量和字段

  • 7.1 常量
  • 7.2 字段

第八章 方法

  • 8.1 实例构造器和类(引用类型)
  • 8.2 实例构造器和结构(值类型)
  • 8.3 类型构造器
    • 值类型的类型构造器什么时候会被调用 (思考,强烈建议动手实践)
  • 8.4 操作符重载方法
  • 8.5 转换操作符方法
  • 8.6 扩展方法(建议动手实践)
  • 8.7 分部方法(建议动手实践)

第九章 参数

  • 9.1 可选参数和命名参数(建议动手实践)
  • 9.2 隐式类型的局部变量(建议动手实践)
  • 9.3 以传引用的方式向方法传递参数
    • out和ref的区别与联系 (p190-195,强烈建议动手实践,查看IL)
  • 9.4 向方法传递可变的参数
    • Concat方法与params(p197)
  • 9.5 参数和返回类型的设计规范
  • 9.6 常量性
    • 什么是不可变 (思考)

第十章 属性

  • 10.1 无参属性
    • 属性的本质 (p203-p205)
    • 对象和集合初始化器(p208)
    • 匿名类型(p209)
    • Tuple类型
  • 10.2 有参属性
    • 有参属性的概念(p214-217)
    • IndexerName特性(p217-218)
  • 10.3 调用属性访问器方法时的性能
  • 10.4 属性访问器的可访问性
  • 10.5 泛型属性访问器方法

第十一章 事件

  • 11.1 设计要公开事件的类型
    • 事件的定义流程(p222-226,建议动手实践)
    • 如何以线程安全的方式引发事件 (p225)
  • 11.2 编译器如何实现事件
    • 事件的本质,事件与委托的关系,事件怎么做到线程安全 (p227-228)
  • 11.3 设计侦听事件的类型(建议动手实践)
  • 11.4 显示实现事件(建议动手实践)

第十二章 泛型

  • 12.1 FCL中的泛型
  • 12.2 泛型基础结构
    • 开放类型和封闭类型 (p239-240,建议动手实践)
    • 泛型类型和继承(p240,建议动手实践)
    • 泛型类型同一性(p242)
    • 代码爆炸(p243)
  • 12.3 泛型接口
  • 12.4 泛型委托
  • 12.5 委托和接口的逆变和协变泛型类型实参
  • 12.6 泛型方法
  • 12.7 泛型和其他成员
  • 12.8 可验证性和约束
    • 主要约束(p252)
    • 次要约束(p253)
    • 构造器约束(p254)
    • 其他可验证性问题(p254-257)

第十三章 接口

  • 13.1 类和接口继承
  • 13.2 定义接口
  • 13.3 继承接口
  • 13.4 关于调用接口方法的更多探讨
  • 13.5 隐式和显式接口方法实现(幕后发生的事情)
  • 13.6 泛型接口
  • 13.7 泛型和接口约束
  • 13.8 实现多个具有相同方法名和签名的接口
  • 13.9 用显示接口方法实现来增加编译时类型安全
  • 13.10 谨慎使用显示接口方法实现
  • 13.11 设计:基类还是接口

第十四章 字符、字符串和文本处理

  • 14.1 字符
  • 14.2 System.String类型
    • 字符串是不可变的 (p284)
    • 比较字符串
    • 语言文化
    • 字符串留用 (p290-292)
    • 字符串池 (p293)
    • 检查字符串中的字符和文本元素
    • 其他字符串操作
  • 14.3 高效率构造字符串
    • 构造StringBuilder对象(p296)
    • StringBuilder的成员(p297-298)
  • 14.4 获取对象的字符串表示: ToString
  • 14.5 解析字符串来获取对象: Parse
  • 14.6 编码:字符和字节的相互转换
    • UTF-8、UTF-16、UTF-32等编码的区别(p309)
    • 编码和解码(p309-315)
  • 14.7 安全字符串

第十五章 枚举类型

  • 15.1 枚举类型
    • 枚举类型的本质 (p320)
    • 枚举类型如何更改基础类型(p321)
    • 枚举类型是引用类型还是值类型,System.Enum是引用类型还是值类型 (思考)
  • 15.2 位标志
  • 15.3 向枚举类型添加方法

第十六章 数组

  • 16.0 数组概述(虽然没有标题,但是非常重要)
    • 数组是引用类型 (p329)
    • 数组的内存结构 (p330)
    • 一维数组、多维数组、0基数组、非0基数组的相关概念 (p330-331)
  • 16.1 初始化数组元素
  • 16.2 数组转型
    • Array.Copy方法做的事情 (p334)
  • 16.3 所有数组都隐式派生自System.Array
  • 16.4 所有数组都隐式实现IEnumerable,ICollection和IList
  • 16.5 数组的传递和返回
  • 16.6 创建下限非零的数组
  • 16.7 数组的内部工作原理
  • 16.8 不安全的数组访问和固定大小的数组

第十七章 委托

  • 17.1 初识委托
  • 17.2 用委托回调静态方法
  • 17.3 用委托回调实例方法
  • 17.4 委托揭秘
  • 17.5 用委托回调多个方法(委托链)
    • 委托是不可变的吗 (思考)
  • 17.6 委托定义不要太多(泛型委托)
  • 17.7 C#为委托提供的简化语法
    • 简化语法1:不需要构造委托对象(p360)
    • 简化语法2:不需要定义回调方法(lambda表达式) (p361)
    • 简化语法3:局部变量不需要手动包装到类中即可传给回调方法 (p364)
  • 17.8 委托和反射

第十八章 定制特性

  • 18.1 使用定制特性
  • 18.2 定义自己的特性类
  • 18.3 特性构造器和字段/属性数据类型
  • 18.4 检测定制特性
    • IsDefined、GetCustomAttribute、GetCustomAttributes (p379-382)
  • 18.5 两个特性实例的相互匹配
  • 18.6 检测定制特性时不创建从Attribute派生的对象
  • 18.7 条件特性类

第十九章 可空值类型

  • 19.0 System.Nullable<T>
  • 19.1 C#对可空值类型的支持
  • 19.2 C#的空接合操作符
  • 19.3 CLR对可空值类型的特殊支持
    • 可空值类型的装箱(p394)
    • 可空值类型的拆箱(p395)
    • 通过可空值类型调用GetType
    • 通过可空值类型调用接口方法

第二十章 异常和状态管理

  • 20.1 定义异常
  • 20.2 异常处理机制
    • try块(p402)
    • catch块 (p402-403)
    • finally块 (p404-406)
  • 20.3 System.Exception类
    • System.Exception的公共属性 (p407)
  • 20.4 FCL定义的异常类
  • 20.5 抛出异常
  • 20.6 定义自己的异常类
  • 20.7 用可靠性换取开发效率
  • 20.8 设计规范和最佳实践
  • 20.9 未处理的异常
  • 20.10 对异常进行调试
  • 20.11 异常处理的性能问题
  • 20.12 约束执行区域(CER)
  • 20.13 代码协定

第二十一章 托管堆和垃圾回收(全部高能)

  • 21.1 托管堆基础
  • 21.2 代:提升性能
    • 第0、1、2代 (p454-457)
    • 垃圾回收触发条件(p458-459)
    • 大对象(p459)
    • 垃圾回收模式 (p459-462)
    • 强制垃圾回收(p462-463)
    • 监视应用程序的内存使用
  • 21.3 使用需要特殊清理的类型
    • SafeHandle、CriticalFinalizerObject (p467)
    • IDisposable、Dispose (p471)
    • GC为本机资源提供的其他功能 (p475-479,强烈建议动手实践)
    • 终结的内部工作原理 (p479-481)
    • 手动监视和控制对象的生存期 (p481-487)

第二十二章 CLR寄宿和AppDomain

  • 22.1 CLR寄宿
  • 22.2 AppDomain
    • AppDomain寄宿的结构图(p493)
    • 跨越AppDomain边界访问对象 (p494-504)
  • 22.3 卸载AppDomain
  • 22.4 监视AppDomain
  • 22.5 AppDomainFirstChance异常通知
  • 22.6 宿主如何使用AppDomain
  • 22.7 高级宿主控制

第二十三章 程序集加载和反射

  • 23.1 程序集加载
    • Load和LoadFrom等方法(p516-519)
  • 23.2 使用反射构建动态可扩展应用程序
  • 23.3 反射的性能
  • 23.4 设计支持加载项的应用程序
  • 23.5 使用反射发现类型的成员

第二十四章 运行时序列化

⬆︎TOP