Методы System.Type.GetType

В этой статье приводятся дополнительные замечания к справочной документации по этому API.

GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) Используйте перегрузку метода и связанные с ней перегрузки (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>)иGetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) для замены реализации GetType метода по умолчанию более гибкими реализациями. Предоставляя собственные методы, разрешающие имена типов и имена сборок, содержащих их, можно выполнить следующие действия:

  • Управление версией сборки, из которой загружается тип.
  • Укажите другое место для поиска имени типа, которое не содержит имя сборки.
  • Загрузка сборок с использованием частичных имен сборок.
  • Возвращает подклассы System.Type , которые не создаются средой CLR.

Например, в сериализации версии этот метод позволяет искать сборку "лучшего соответствия" с помощью частичного имени. Для других перегрузок GetType метода требуется имя типа с указанием сборки, включающее номер версии.

Альтернативные реализации системы типов могут потребоваться возвращать подклассы System.Type , которые не создаются средой CLR. Все типы, возвращаемые другими перегрузками метода, являются типами GetType среды выполнения.

Примечания об использовании

Эта перегрузка метода и связанные с ней перегрузки анализируются typeName в имя типа и имя сборки, а затем разрешают имена. Разрешение имени сборки происходит перед разрешением имени типа, так как имя типа должно быть разрешено в контексте сборки.

Примечание.

Если вы не знакомы с понятием имен типов с указанием сборки, ознакомьтесь со свойством AssemblyQualifiedName .

Если typeName имя сборки не задано, разрешение сборки пропускается. Имена неквалифицированных типов можно разрешать в контексте mscorlib.dll/System.Private.CoreLib.dll или текущей выполняемой сборки или при необходимости предоставить сборку в параметре typeResolver . Эффекты включения или исключения имени сборки для различных типов разрешения имен отображаются в виде таблицы в разделе разрешения смешанных имен.

Общие заметки об использовании:

  • Не передайте методы в неизвестные или ненадежные вызывающие методы assemblyResolvertypeResolver . Рекомендуется использовать только методы, предоставленные пользователями или знакомые им.

    Внимание

    Использование методов из неизвестных или недоверенных вызывающих объектов может привести к повышению привилегий для вредоносного кода.

  • Если опущены assemblyResolver параметры и/или typeResolver параметры, значение throwOnError параметра передается методам, выполняющим разрешение по умолчанию.

  • Если throwOnError это trueтак, этот метод создает TypeLoadException исключение, когда typeResolver возвращается null, и FileNotFoundException когда assemblyResolver возвращается null.

  • Этот метод не перехватывает исключения, вызванные assemblyResolver и typeResolver. Вы несете ответственность за все исключения, создаваемые методами сопоставителя.

Разрешение сборок

Метод assemblyResolver получает AssemblyName объект, который создается путем синтаксического анализа имени строковой сборки, включенной в typeName. Если typeName имя сборки не содержится, assemblyResolver он не вызывается и null передается в typeResolver.

Если assemblyResolver он не указан, для поиска сборки используется стандартное проверка сборки. Если assemblyResolver этот метод указан, метод не выполняет стандартное проверка. В этом случае необходимо убедиться, GetType что assemblyResolver все сборки, которые вы передаете в него.

Метод должен возвращатьnull, assemblyResolver если сборка не может быть разрешена. Если assemblyResolver возвращаетсяnull, typeResolver не вызывается и не выполняется дальнейшая обработка; кроме того, при FileNotFoundExceptionthrowOnErrortrueналичии возникает исключение.

Если передано AssemblyNameassemblyResolver частичное имя, одна или несколько его частей.null Например, если у него нет версии, Version свойство имеет значение null. Version Если свойство, CultureInfo свойство и GetPublicKeyToken метод возвращаютсяnull, то было предоставлено только простое имя сборки. Метод assemblyResolver может использовать или игнорировать все части имени сборки.

Эффекты различных параметров разрешения сборок отображаются в виде таблицы в разделе " Разрешение смешанных имен" для простых и сборочных имен.

Разрешение типов

Если typeName имя сборки не указано, typeResolver всегда вызывается. Если typeName указывает имя сборки, typeResolver вызывается только при успешном разрешении имени сборки. Если assemblyResolver или стандартная проверка сборки возвращается null, typeResolver не вызывается.

Метод typeResolver получает три аргумента:

  • Сборка для поиска или null если typeName не содержит имя сборки.
  • Простое имя типа. В случае вложенного типа это самый внешний содержащий тип. В случае универсального типа это простое имя универсального типа.
  • Логическое значение, указывающее true , следует ли игнорировать регистр имен типов.

Реализация определяет способ использования этих аргументов. Метод должен возвращатьnull, typeResolver если он не может разрешить тип. Если typeResolver возвращается null и throwOnError является true, эта перегрузка GetType вызывает TypeLoadExceptionисключение.

Эффекты различных параметров разрешения типов отображаются в виде таблицы в разделе " Разрешение смешанных имен" для простых и сборочных имен.

Разрешение вложенных типов

Если typeName является вложенным типом, передается typeResolverтолько имя самого внешнего содержащего типа. При typeResolver возврате этого типа GetNestedType метод вызывается рекурсивно, пока не будет разрешен самый внутренний вложенный тип.

Разрешение универсальных типов

Вызывается GetType рекурсивно для разрешения универсальных типов: сначала для разрешения самого универсального типа, а затем для разрешения аргументов типа. Если аргумент типа является универсальным, GetType вызывается рекурсивно для разрешения его аргументов типа и т. д.

assemblyResolver Сочетание и typeResolver то, что вы предоставляете, должны быть способны разрешать все уровни этого рекурсии. Например, предположим, что вы предоставляете элемент assemblyResolver управления загрузкой MyAssembly. Предположим, вы хотите разрешить универсальный тип Dictionary<string, MyType> (Dictionary(Of String, MyType) в Visual Basic). Можно передать следующее имя универсального типа:

"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"

Обратите внимание, что MyType является единственным аргументом типа с указанием сборки. Имена Dictionary<TKey,TValue> и String классы не являются сборками. Необходимо typeResolver иметь возможность обрабатывать сборку или null, так как она будет получать nullDictionary<TKey,TValue> и String. Он может обработать этот случай путем вызова перегрузки метода, принимающего GetType строку, так как оба имена неквалифицированных типов находятся в mscorlib.dll/System.Private.CoreLib.dll:

Type t = Type.GetType(test,
                      (aName) => aName.Name == "MyAssembly" ?
                          Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") : null,
                      (assem, name, ignore) => assem == null ?
                          Type.GetType(name, false, ignore) :
                              assem.GetType(name, false, ignore)
                     );
let t =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else null),
        fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr))

Метод assemblyResolver не вызывается для типа словаря и типа строки, так как эти имена типов не являются сборками.

Теперь предположим, что вместо System.Stringэтого первый универсальный тип аргумента имеет следующий YourTypeвид:YourAssembly

"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"

Так как эта сборка не является ни mscorlib.dll/System.Private.CoreLib.dll, ни текущей выполняемой сборкой, невозможно разрешить YourType без имени, указанного в сборке. Так как ваш assemblyResolve вызов будет вызываться рекурсивно, он должен иметь возможность обрабатывать этот случай. Вместо возврата null для сборок, отличных MyAssemblyот сборки, теперь она выполняет загрузку сборки с помощью предоставленного AssemblyName объекта.

Type t2 = Type.GetType(test,
                       (aName) => aName.Name == "MyAssembly" ?
                           Assembly.LoadFrom(@".\MyPath\v5.0\MyAssembly.dll") :
                           Assembly.Load(aName),
                       (assem, name, ignore) => assem == null ?
                           Type.GetType(name, false, ignore) :
                               assem.GetType(name, false, ignore), true
                      );
let t2 =
    Type.GetType(test,
        (fun aName ->
            if aName.Name = "MyAssembly" then
                Assembly.LoadFrom @".\MyPath\v5.0\MyAssembly.dll"
            else Assembly.Load aName),
        (fun assem name ignr ->
            if assem = null then
                Type.GetType(name, false, ignr)
            else
                assem.GetType(name, false, ignr)), true)

Разрешение имен типов с помощью специальных символов

Некоторые символы имеют особые значения в именах с указанием сборки. Если имя простого типа содержит эти символы, символы вызывают ошибки синтаксического анализа, если простое имя является частью имени, заданного сборкой. Чтобы избежать ошибок синтаксического анализа, необходимо экранировать специальные символы с обратной косой чертой, прежде чем передать в метод полное имя сборки GetType . Например, если тип называетсяStrange]Type, экранный символ должен быть добавлен перед квадратной скобкой следующим образом: Strange\]Type

Примечание.

Имена с такими специальными символами не могут быть созданы в Visual Basic или C#, но можно создавать с помощью общего промежуточного языка (CIL) или путем создания динамических сборок.

В следующей таблице показаны специальные символы для имен типов.

Символ Значение
, (запятая) Разделитель имен с указанием сборки.
[] (квадратные скобки) Как пара суффикса указывает тип массива; в качестве пары разделителей заключены универсальные списки аргументов и имена с указанием сборки.
& (амперсанд) Как суффикс указывает, что тип является ссылочным типом.
* (звездочка) Как суффикс указывает, что тип является типом указателя.
+ (плюс) Разделитель для вложенных типов.
\ (обратная косая черта) Escape-символ.

Такие свойства, как AssemblyQualifiedName правильное возвращение правильно экранированных строк. Необходимо правильно передать в метод экранированные строки GetType . В свою очередь, GetType метод правильно передает имена и typeResolver методы разрешения типов по умолчанию. Если вам нужно сравнить имя с незакрытым именем typeResolver, необходимо удалить escape-символы.

Разрешение смешанных имен

В следующей таблице приведены сведения о взаимодействии между assemblyResolvertypeResolver, и разрешением имен по умолчанию для всех сочетаний имен типа и имени сборки вtypeName:

Содержимое имени типа Метод сопоставителя сборок Метод сопоставителя типов Результат
тип, сборка null null Эквивалентно вызову перегрузки Type.GetType(String, Boolean, Boolean) метода.
тип, сборка Предоставляются null assemblyResolver возвращает сборку или возвращается null , если она не может разрешить сборку. Если сборка разрешена, Assembly.GetType(String, Boolean, Boolean) перегрузка метода используется для загрузки типа из сборки; в противном случае попытка разрешения типа отсутствует.
тип, сборка null Предоставляются Эквивалентно преобразованию имени сборки в AssemblyName объект и вызову Assembly.Load(AssemblyName) перегрузки метода для получения сборки. Если сборка разрешена, она передается typeResolverв; в противном случае не вызывается и typeResolver не предпринимается дальнейших попыток разрешения типа.
тип, сборка Предоставляются Предоставляются assemblyResolver возвращает сборку или возвращается null , если она не может разрешить сборку. Если сборка разрешена, она передается typeResolverв; в противном случае не вызывается и typeResolver не предпринимается дальнейших попыток разрешения типа.
type null, предоставленный null Эквивалентно вызову перегрузки Type.GetType(String, Boolean, Boolean) метода. Так как имя сборки не указано, выполняется поиск только mscorlib.dll/System.Private.CoreLib.dll и выполняемой сборки. Если assemblyResolver он указан, он игнорируется.
type null, предоставленный Предоставляются typeResolver вызывается и null передается для сборки. typeResolver может предоставить тип из любой сборки, включая сборки, которые она загружает для цели. Если assemblyResolver он указан, он игнорируется.
сборка null, предоставленный null, предоставленный FileLoadException Создается исключение, так как имя сборки анализируется так, как если бы это было имя типа с указанием сборки. Это приводит к недопустимому имени сборки.