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

Vin*_*cio 5 .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都包含大多数相同的类型.

Han*_*ant 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类就是一个很好的例子.在.NET 4.0中,它存在于System.Core.dll中,在4.5及以上,它现在位于mscorlib.dll中.如果这些副本不再存在会更好,不幸的是System.CodeDom,sgen.exe和传统工具依赖于它们在那里.当程序在安装了不同框架版本的另一台机器上运行时,使用它们作为参考可能非常麻烦.

因此,请查看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]属性.你会在那里找到的那​​些:

[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
Run Code Online (Sandbox Code Playgroud)

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

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

  • 在我所知道的任何地方都没有记录.像这样的东西通常最终会在博客中被记录下来,但David Kean和Mircea Trofin都不是认真的博主.我从研究参考组件中反过来设计了这个,花了我一段时间.这是缺少的手册. (2认同)