日期:2014-01-31  浏览次数:20409 次


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中调用,则需要