Различия декомпиляции ILDasm, mscorlib и System.Runtime в зависимости от каталога
Я играл с 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 ответ
Сборки, которые вы нашли в C:\Program Files (x86)\ Ссылочные сборки, являются ссылочными сборками. Они довольно специфичны для.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. И самое заметное изменение - у него больше нет расширения оболочки, которое мешало вам переходить к файлам в этом каталоге. Вы можете напрямую перемещаться по структурам папок 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
Может быть, вы можете видеть, что происходит сейчас, 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 является основным бенефициаром.