Chapter 3
1. 工作人员划分了程序集以后,他们大部分时间就用来考虑类型如何工作,如何联系了。所有的表示类型的构建(类,结构,枚举等)最终会映射到CLR的类型定义上。
2. CLR类型(CLR type)是命名的可重用抽象体。CLR类型的描述存放在CLR模块的元数据中,该模块还包含是类型工作所需要的CIL或者本机代码。
3. 完全限定的CLR类此哪个名包括三个部分:程序集名字、可选的命名空间前缀和类型名称。
4. 公共类型系统比大多数编程语言所能处理的类型要宽得多。提交给ECMA的CLI部分被划分为一个CTS子集,它能被所有CLI兼容的语言支持。这个子集叫做CLS(Common Language Specification,公共语言规范)。组件强烈推荐开发者使用符合CLS的规范以增强组件的可访性功能。CLI定义了一个特性System.CLSCompliant,它指示编译器对所有公有成员实施CLS遵从性检查。
5. CLR类型定义由零个或多个成员(member)组成。类型的每个成员都有自己的访问修饰符(access modifier)控制对于成员的访问。按实例访问(per-instance member)/ 按类型访问(per-type member,即static/Shared等)。
6. CTS有三种基本类型的成员:字段、方法和嵌套类型。字段是一个命名的存储单元,它隶属于所声明的类型。方法是一个命名的操作,它可以被调用和执行。嵌套类型则是一种简单的辅助类型。其他类型成员(属性、事件)是以附加元数据的形式出现的方法。
7. 类型的字段控制内存如何分配。CLR使用类型的字段来决定分配多少内存给这个类型。CLR会给static字段分配一次内存(类型首次加载时)。
8. CLR每次分配类型实例时,都会为non-static字段分配内存。
9. 在分配内存时,CLR初始化static字段并赋予默认值。数值类型默认为零,布尔类型默认为false,引用类型为null。
10. 默认情况下,确切的内存布局是不透明的。CLR使用虚拟内存布局,并且会经常重新排序字段以优化访问和使用。
11. const在编译时会被内联进所有使用它的地方(注意这样做带来的现象),const字段在初始化值在编译时必须是已知的;initonly字段CLR会在引用处调用它的值,initonly字段只能在声明时或者构造函数里赋值。
12. CLR允许方法为最后一个参数使用[System.ParamArrayAttribute]特性。
13. 由于编译器可能有不同的特性,所以尽量使用明确的重载。
14. 嵌套类型往往定义为辅助对象,如迭代器、序列化器。
15. 嵌套类型能防止对命名空间的污染。CLR的嵌套类型总是被声明为静态成员,它不隶属于任何特定的实例,嵌套类型的名字有外部类型名字限定。
16. 嵌套类型能做到对声明类型的私有成员进行无限制访问。
17. 静态字段初始化顺序:声明à静态构造函数(.cctor)。
18. CLR将静态初始化方法的调用延迟到第一个静态字段被访问的时候(beforefieldinit特性)。静态初始化方法在生成这个类的实例之前不一定会被调用。
19. 当基类型和派生类型存在同名的方法时,CLR支持两种基本的策略:按名字隐藏(hide-by-name)和按签名隐藏(hide-by-signature)。通过在派生类的方法上上添加hidebysig元数据特性与否来确定。C#总是按签名隐藏的。
20. 强烈推荐不要在一个non-sealed类型的构造函数中调用虚方法,因为派生类的虚方法的部分还没有执行到,因此可能会导致不可预见的问题
21. 构造派生类时的执行顺序:初始化派生类字段à构造基类à调用派生类(“构造基类”是一个递归的过程)。
22. 为了保证派生类正确地调用基类的构造函数,可以把基类的构造函数修饰为internal,这样保证了只有自己写的程序集才能够调用该构造函数。