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

2023-12-25

我一直在玩 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 都包含大部分相同的类型。


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

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

您在 C:\Windows\Microsoft.NET\Framework\v4.0.30319 中找到的程序集是 GAC 中的程序集的副本。无论您实际安装的框架版本是什么。你应该never将这些程序集用于任何用途。虽然许多程序集仍然有 [AssemblyVersion("4.0.0.0")],但它们的内容却截然不同,特别是在 4.0 和 4.5 之间。您可以在文档中看到这一点,扩展属性类 http://msdn.microsoft.com/en-us/library/system.runtime.compilerservices.extensionattribute%28v=vs.110%29.aspx就是一个很好的例子。在 .NET 4.0 中,它位于 System.Core.dll 中,在 4.5 及更高版本中,它现在位于 mscorlib.dll 中。如果这些副本不再存在那就更好了,不幸的是 System.CodeDom、sgen.exe 和遗留工具依赖于它们的存在。使用它们作为参考可以很麻烦 https://stackoverflow.com/a/13750130/17034当程序在安装了不同框架版本的另一台机器上运行时。

因此,查看 GAC 中的程序集即可了解内容really发生在运行时。自 .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 程序集确实相当空。然而,您可能错过了清单中最重要的细节。它包含一个lot[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

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

前一句中的“桌面版本”是解释为什么这样做的关键。有many.NET Framework 版本,它们在 System.Runtime 中有不同的转发器。这些适配器组件为 Microsoft 带来了额外的间接级别。它可以帮助您编写与平台无关的 .NET 代码,并且无论您是在桌面、商店应用程序、Silverlight 浏览器、XBox 游戏控制台还是手机上执行,都可以毫无变化地运行。尽管后者有一个相当不同的框架,一个名为 .NETCore 的小得多的框架。可移植类库项目模板是主要受益者。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ILDasm、mscorlib 和 System.Runtime 反编译差异取决于目录 的相关文章

随机推荐