在多个.cs文件中物理编码的单个文件程序集和具有多个.NetModules的多文件程序集之间有什么区别和优势?
我的教授说,当这些组件加载或在jitting期间可以实现差异。并非所有多文件程序集的.Netmodules都会立即加载。但即使他不确定。有人可以澄清一下吗?
答案 0 :(得分:7)
假设我们有两个名为
的.cs文件
RUT.cs
,其中包含很少使用的类型
FUT.cs
,其中包含常用类型
现在csc /t:module RUT.cs
此行导致C#编译器创建RUT.netmodule文件。此文件是标准DLL PE
文件,但是,CLR本身无法加载它。
接下来让我们将常用类型编译到自己的模块中。我们将制作这个模块
程序集清单的守护者,因为这些类型经常被使用。事实上,因为
此模块现在将代表整个程序集,我将输出文件的名称更改为
JeffTypes.dll而不是称它为FUT.dll:
csc /out:JeffTypes.dll /t:library /addmodule:RUT.netmodule FUT.cs
该行告诉C#编译器编译FUT.cs文件以生成JeffTypes.dll文件。 因为指定了/ t:library,所以包含清单元数据表的DLL PE文件是 发送到JeffTypes.dll文件中。 /addmodule:RUT.netmodule开关告诉编译器 RUT.netmodule是一个应该被视为程序集一部分的文件。具体来说, / addmodule开关告诉编译器将文件添加到FileDef清单元数据表中 并将RUT.netmodule的公开导出类型添加到ExportedTypesDef清单中 元数据表。
RUT.netmodule文件包含通过编译RUT.cs生成的IL代码。这个文件也 包含描述类型,方法,字段,属性,事件等的元数据表 在那上面由RUT.cs.定义。元数据表还描述了类型,方法和 所以这是由RUT.cs.引用的。 JeffTypes.dll是一个单独的文件。像RUT.netmodule一样, 此文件包含通过编译FUT.cs生成的IL代码,还包括类似的定义 和参考元数据表。但是,JeffTypes.dll包含其他清单 元数据表,使JeffTypes.dll成为一个程序集。其他清单元数据表 描述组成程序集的所有文件(JeffTypes.dll文件本身和 RUT.netmodule文件)。清单元数据表还包括所有公共类型 从JeffTypes.dll和RUT.netmodule导出
现在,如果某些clinet代码重新启动到JeffTypes.dll正在执行,
当第一次调用方法时,
CLR检测方法引用的类型作为参数,返回值或作为
局部变量。然后CLR尝试加载包含的引用程序集的文件
表现。如果正在访问的类型在此文件中,则CLR执行其内部簿记,
允许使用该类型。如果清单指示引用的类型不同
文件,CLR尝试加载必要的文件,执行其内部簿记,和
允许访问类型。 CLR仅在引用方法时加载程序集文件
调用卸载程序集中的类型。
这意味着运行应用程序,所有文件
来自引用的程序集不需要存在。
因此,可以在NetModules中编译较少使用的源类,并在必要时加载,提高性能和减少Dll文件大小简化更改管理和部署过程 。
图片以及 jeffrey richter