TransWikia.com

TypeLoadException Не удаётся загрузить тип

Stack Overflow на русском Asked by D .Stark on November 18, 2021

Встретился с такой проблемой.

Скомпилировал сборку под .NET 4.5. При попытке запуска на компьютере, где максимальная установленная версия .NET – 4.0, выпадает исключение TypeLoadException на тип в сборке System.Windows.Input. Разве не должна вылетать ошибка с несоответствием версии сборки и версии, установленной на ПК? Может быть я что то упускаю? При чём в сборку включено ещё 11 ссылок на библиотеки отсутсвующей версии .NET, но исключения кроме этого больше не выпадают. По идее же все сборки FCL имеют строгое имя и с каждой новой версией .NET – разное.

One Answer

По идее же все сборки FCL имеют строгое имя и с каждой новой версией .NET - разное.

Только с каждой новой версией CLR, а не с каждым выпуском .NET. Т.е. 2.0-3.5 и 4.Х имеют разное строгое имя, а 4.0 и 4.5 - одинаковое.

Например, открываем сборку PresentationCore из .NET 4.8 в IL Disassembler, и видим такой фрагмент манифеста:

.assembly PresentationCore
{
  (...)

  .ver 4:0:0:0

  (...)
} 

Теперь откроем приложение, которое на нее ссылается, при целевой платформе .NET 4.5:

.assembly extern PresentationCore
{
  .ver 4:0:0:0
}

То есть версия в плане строгого имени везде 4.0. Сборка, конечно, содержит атрибут, который позволяет определить реальную целевую платформу:

.custom instance void [mscorlib]System.Runtime.Versioning.TargetFrameworkAttribute::.ctor(string) 
= ( 01 00 1A 2E 4E 45 54 46 72 61 6D 65 77 6F 72 6B   // ....NETFramework
    2C 56 65 72 73 69 6F 6E 3D 76 34 2E 35 01 00 54   // ,Version=v4.5..T
    0E 14 46 72 61 6D 65 77 6F 72 6B 44 69 73 70 6C   // ..FrameworkDispl
    61 79 4E 61 6D 65 12 2E 4E 45 54 20 46 72 61 6D   // ayName..NET Fram
    65 77 6F 72 6B 20 34 2E 35 )                      // ework 4.5

Но он только для информации, при выполнении он ни на что не влияет (значение целевой платформы при проверке берется из app.config)

Также и реальную версию установленной сборки можно узнать из свойств файла

file properties

(C:WindowsMicrosoft.NETFrameworkv4.0.30319WPFPresentationCore.dll)

Опять же, это значение ни на что не влияет. Оно хранится в Win32-ресурсе VERSION, а не в манифесте сборки.

Тут неизбежно возникает вопрос, как вообще работает понятие "целевая платформа", если версия везде одинаковая? Суть в следующем - когда вы выбираете целевую платформу, вы этим выбираете набор reference assemblies, соответствующий определенному выпуску .NET. Он содержит набор API, которые присутствуют в этом выпуске, и только их. Таким образом, если вы захотите использовать API, который появился в более новой версии, это не скомпилируется, и даже в IntelliSense вы его не увидите.

Скомпилировал сборку под .NET 4.5. При попытке запуска на компьютере, где максимальная установленная версия .NET - 4.0 выпадает исключение TypeLoadException

В этом случае приложение запустилось только потому, что вы удалили стандартный app.config, который указывает целевую платформу. Если бы он был, загрузчик бы вывел нормальное сообщение "Установите .NET Framework 4.5".

Answered by MSDN.WhiteKnight on November 18, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP