ILDasm,mscorlib和System.Runtime反编译的差异取决于目录

时间:2014-03-30 11:29:40

标签: .net clr ildasm

我一直在玩ILDasm并注意到:

  • 反编译C:\Windows\Microsoft.NET\Framework\v4.0.30319\System.Runtime.dll (36KB)只会返回一个清单文件。反编译C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.dll (114KB)将返回清单和程序集中的所有类型。

  • 反编译C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\mscorlib.dll (38KB)只返回一个清单文件,反编译C:\Windows\Microsoft.NET\Framework\v4.0.30319\mscorlib.dll (5171KB)会返回清单以及程序集中的所有类型。

我找不到任何关于为什么以这种方式构建组件的信息。

两个汇编目录有什么区别,为什么文件系统上有两个副本?为什么两个程序集中的类型都重复? System.Runtime和mscorlib都包含大多数相同的类型。

1 个答案:

答案 0 :(得分:14)

在C:\ Program Files(x86)\ Reference Assemblies中找到的程序集是引用程序集。它们在.NET 4.0及更高版本中相当特殊,它们不包含任何代码,只包含类型声明。编译器仅使用此类程序集中的元数据来编译代码。在运行时,您将获得一个非常的不同程序集,它将从GAC中检索。

请注意,您将在该目录中找到许多版本的System.Runtime.dll,特别是.NETPortable目录中有许多配置文件,每个配置文件都有自己的参考程序集副本。使用不同类型的集合,适合该特定配置文件。

您在C:\ Windows \ Microsoft.NET \ Framework \ v4.0.30319中找到的程序集是GAC中的程序集的副本。无论您实际安装的是什么版本的框架。你应该从不使用这些程序集。虽然许多组件仍然有[AssemblyVersion(“4.0.0.0”)],但它们的内容却截然不同,特别是在4.0到4.5之间。您可以在文档中看到这一点,ExtensionAttribute class就是一个很好的例子。在.NET 4.0中,它存在于System.Core.dll中,在4.5及以上,它现在位于mscorlib.dll中。如果这些副本不再存在会更好,不幸的是System.CodeDom,sgen.exe和传统工具依赖于它们在那里。当程序在安装了不同框架版本的另一台机器上运行时,将它们用作引用可以be very troublesome

请查看GAC中的程序集,了解真正在运行时发生的情况。自从.NET 4.0以来,它也发生了重大变化,它现在存在于另一个目录中。以前在c:\ windows \ assembly中,现在位于c:\ windows \ microsoft.net \ assembly中。并且最明显的变化是,它不再具有阻止您导航到该目录中的文件的shell扩展。您可以直接导航GAC文件夹结构。由于包含非托管代码的程序集(如mscorlib.dll)存储在单独的目录中,因此它有点令人费解。看看,你可以毫不费力地搞清楚这个计划。

你会发现C:\ Windows \ Microsoft.NET \ assembly \ GAC_MSIL \ System.Runtime \ v4.0_4.0.0.0__b03f5f7f11d50a3a \ System.Runtime.dll程序集确实是空的。您可能错过了清单中最重要的细节。它包含[TypeForwardedTo]属性的 lot 。你会在那里找到的那​​些片段:

[assembly: TypeForwardedTo(typeof(Action))]
[assembly: TypeForwardedTo(typeof(Action<>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,,>))]
[assembly: TypeForwardedTo(typeof(Action<,,,,,,,,,,,,,,,>))]
// etc, many more

也许你可以看到现在发生了什么,System.Runtime.dll根本不包含任何代码。它是一种适配器,可以将类型从一个程序集转发到另一个程序集。 .NET的桌面版本将类型转发到mscorlib.dll,System.dll,System.ComponentModel.Composition和System.Core。

上一句中的“桌面版本”是解释原因的关键。有许多 .NET Framework版本,它们在System.Runtime中有不同的转发器。这些适配器组件为Microsoft提供了额外的间接级别。它可以帮助您编写与平台无关的.NET代码,无论您是在桌面,Store应用程序,Silverlight浏览器,XBox游戏机,手机上执行,都可以无需更改即可运行。即使后者有一个相当显着不同的框架,一个名为.NETCore的小框架。可移植类库项目模板是主要的受益者。