Chapter 2
1. CLR程序存在于模块中(module)中。一个CLR模块是一个字节流,储存在一个文件(本地或远程服务器)。
2. CLR模块采用WinNT的PE(Portable Executable)/COFF(Common Object File Format)格式的扩展版。CLR模块也是有效的Win32模块,可以通过LoadLibrary系统调用加载。CLR模块用到的PE/COFF的功能极少,大部分内容是使用PE/COFF文件的.text部分。
3. CLR模块包括代码、元数据和资源。代码使用CIL(Common Intermediate Language)格式存放(个人理解:这个和MSIL或者IL是一个东西)。模块的元数据描述了模块中定义的类型,包含名字、继承关系、方法签名和依赖关系等。模块的资源由静态的只读数据组成(字符串、位图等)。
4. (/t:exe、/t:winexe、/t:library、/t:module)module产生的是“未加工”的模块(.netmodule)。/t:library编译产生的模块(.dll)包含元数据。/t:exe生成控制台程序、/t:winexe产生Win程序。
5. 起点为四种形式之一:static void Main(){}、static void Main(string[] argv){}、static void Main(){return 0}、static void Main(string[] argv){return 0}。是否有public无所谓,一个程序不可有多个入口,多个Main函数需要在编译时使用/main开关。
6. 程序集(assembly)为一个或多个模块的逻辑集合。程序集通过独立于位置的名字进行引用。这个名字必须翻译为文件系统中或Internet上的物理路径,最终指向一个或多个包含类型定义、代码以及资源的模块。
7. “多模块”的作用就是把“常用”和“不常用”的代码加载区分开来(可以在运行时做到“要什么下载什么”),可以作到使用一种语言写底层,一种语言写界面。
8. 一个模块往往只属于一个程序集,如果需要违反,那么会将这个公用模块产生两个不用的拷贝。
9. 模块依赖于来自其他程序集的类型(至少有mscorlib.dll里的),每个模块都有一个程序集名字列表,然后CLR负责在运行时将这些程序集的名字转换成模块的路径名。
10. 每个程序集有一个程序集清单(assembly manifest),这是元数据的一部分,相当于附加类型定义和代码的附属文件目录。
11. 含有程序集清单的模块首先被CLR加载,然后根据这个清单的内容加载其余不含清单的模块。
12. 引用别的模块使用/addmodule开关,引用别的程序集使用/r开关。
13. 含有程序集清单的模块将包含外部引用程序集的主要列表。列表由程序集中每个模块的依赖关系组成,这样通过加载一个文件就能找到程序集所有的依赖关系。
14. internal导致只对同一程序集的模块可用;public导致所有的代码都可用;private只有该类型的方法才可用;protected使派生类的方法等也能访问该成员;protected和internal可以一起用。
15. 命名空间(namespace)+类名。
16. 每个程序集采用四部分(four-part)名字,作为唯一的标识。这四部分为名称、文化、开发人员、组件版本。这些名字被放在程序集清单里,在加载时,CLR使用四部程序集名字找到正确的组件。
17. 每个程序集的名字都有一个版本号:Major.Minor.Build.Revision,如果没有显式设定这个版本号,那么就是0.0.0.0。System.Reflection.AssemblyVersion能接受各种字符串格式(1.2.d.s等)。
18. CultureInfo特性标识着组件开发所用到的语言和国家代码(语言环境)。含有CultureInfo特性的程序集不能包括代码,必须是“纯资源”的程序集(resource-only)。含代码的程序集是文化无关的(culture-neutral)。
19. 程序集名字包含一个“公钥”(public key),标识组件的开发人员。可以选择使用8位的或者128位的公钥标记,这样就可以标记着相同文件名的不同程序集。
20. 有时候必须手动引用程序集。CLR定义了一个标准格式,用于将程序集的四部分名字编写字符串。这个格式被称为程序集的显示名字(display name):Name, Virsion=X.X.X.X, Culture=[xx-XX | Neutral], PublicKeyToken=[XXXXXXXXXXXXX | Null]。Culture为Neutral表示程序集没有文化限制,PublicKeyToken为null表示不带公钥。简单省略一个部分的限定名字表示允许匹配任何Culture或PublicKeyToken。
21. 一般来说,应该避免使用程序集的部分限定名,否则CLR可能会以非预期的方式运行。可以在配置文件里写全名,然后使用部分名在程序中调用(Assembly assm = Assembly.Load(“XXXX”))。PartialName(上面的XXXX)必须存在于配置文件的PartialName中
22. CLR会尽量少加载不需要的模块,当确实使用了才会加载。这样减少了初始化时间,也减少了运行程序所消耗的资源。CLR加载是由基于类型的JIT编译器触发的,JIT将方法体的CIL编译成机器码时,要访问的局部变量,参数等数据类型会被一起加载。
23. 如果不要CLR屡次的加载模块可以有两种做法:一是定义一些静态字段。二是用手动显式加载。
24. 如果要显式的和程序集交互,需要使用System.Reflection.Assembly的LoadFrom方法,它可以是本地的一个文件,也可以是“file://...”,如果是从非“file://...”的URL中调用,则需要