Методы 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
. Эффекты включения или исключения имени сборки для различных типов разрешения имен отображаются в виде таблицы в разделе разрешения смешанных имен.
Общие заметки об использовании:
Не передайте методы в неизвестные или ненадежные вызывающие методы
assemblyResolver
typeResolver
. Рекомендуется использовать только методы, предоставленные пользователями или знакомые им.Внимание
Использование методов из неизвестных или недоверенных вызывающих объектов может привести к повышению привилегий для вредоносного кода.
Если опущены
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
не вызывается и не выполняется дальнейшая обработка; кроме того, при FileNotFoundExceptionthrowOnError
true
наличии возникает исключение.
Если передано 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
, так как она будет получать null
Dictionary<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-символы.
Разрешение смешанных имен
В следующей таблице приведены сведения о взаимодействии между assemblyResolver
typeResolver
, и разрешением имен по умолчанию для всех сочетаний имен типа и имени сборки в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 Создается исключение, так как имя сборки анализируется так, как если бы это было имя типа с указанием сборки. Это приводит к недопустимому имени сборки. |