Métodos System.Type.GetType
Este artigo fornece observações complementares à documentação de referência para essa API.
Use a sobrecarga do GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) método e suas sobrecargas associadas (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) e GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) para substituir a GetType implementação padrão do método por implementações mais flexíveis. Fornecendo seus próprios métodos que resolvem nomes de tipo e os nomes dos assemblies que os contêm, você pode fazer o seguinte:
- Controle de qual versão de um assembly um tipo é carregado.
- Forneça outro local para procurar um nome de tipo que não inclua um nome de assembly.
- Carregue montagens usando nomes de assembly parciais.
- Retornar subclasses que System.Type não são criadas pelo CLR (Common Language Runtime).
Por exemplo, na serialização tolerante à versão, esse método permite que você procure um assembly "mais adequado" usando um nome parcial. Outras sobrecargas do GetType método exigem um nome de tipo qualificado para assembly, que inclui o número da versão.
Implementações alternativas do sistema de tipos podem precisar retornar subclasses das System.Type que não são criadas pelo CLR, todos os tipos que são retornados por outras sobrecargas do método são tipos de tempo de GetType execução.
Observações de uso
Essa sobrecarga de método e suas sobrecargas associadas analisam typeName
o nome de um tipo e o nome de um assembly e, em seguida, resolvem os nomes. A resolução do nome do assembly ocorre antes da resolução do nome do tipo, porque um nome de tipo deve ser resolvido no contexto de um assembly.
Observação
Se você não estiver familiarizado com o conceito de nomes de tipo qualificados para assembly, consulte a AssemblyQualifiedName propriedade.
Se typeName
não for um nome qualificado para assembly, a resolução do assembly será ignorada. Nomes de tipo não qualificados podem ser resolvidos no contexto de mscorlib.dll/System.Private.CoreLib.dll ou o assembly em execução no momento, ou você pode opcionalmente fornecer um assembly no typeResolver
parâmetro. Os efeitos de incluir ou omitir o nome do assembly para diferentes tipos de resolução de nomes são exibidos como uma tabela na seção Resolução de nomes mistos.
Notas de uso geral:
Não passe métodos para
assemblyResolver
outypeResolver
se eles vierem de chamadores desconhecidos ou não confiáveis. Use apenas métodos fornecidos por você ou com os quais esteja familiarizado.Cuidado
O uso de métodos de chamadores desconhecidos ou não confiáveis pode resultar em elevação de privilégio para código mal-intencionado.
Se você omitir os
assemblyResolver
parâmetros e/outypeResolver
, othrowOnError
valor do parâmetro será passado para os métodos que executam a resolução padrão.Se
throwOnError
fortrue
, esse método lança um TypeLoadException quandotypeResolver
retornanull
e um FileNotFoundException quandoassemblyResolver
retornanull
.Esse método não captura exceções lançadas por
assemblyResolver
etypeResolver
. Você é responsável por quaisquer exceções lançadas pelos métodos do resolvedor.
Resolver assemblies
O assemblyResolver
método recebe um AssemblyName objeto, que é produzido analisando o nome do assembly de cadeia de caracteres incluído no typeName
. Se typeName
não contiver um nome de assembly, assemblyResolver
não é chamado e null
é passado para typeResolver
.
Se assemblyResolver
não for fornecido, a sondagem de montagem padrão será usada para localizar o conjunto. Se assemblyResolver
for fornecido, o GetType método não faz sondagem padrão, nesse caso você deve garantir que você assemblyResolver
possa lidar com todas as montagens que você passar para ele.
O assemblyResolver
método deve retornar null
se o assembly não puder ser resolvido. Se assemblyResolver
retorna null
, typeResolver
não é chamado e não ocorre nenhum processamento adicional, além disso, se throwOnError
for true
, um FileNotFoundException é lançado.
Se o AssemblyName que é passado para assemblyResolver
é um nome parcial, uma ou mais de suas partes são null
. Por exemplo, se ele não tiver versão, a Version propriedade será null
. Se a Version propriedade, a CultureInfo propriedade e o GetPublicKeyToken método retornarem null
, somente o nome simples do assembly foi fornecido. O assemblyResolver
método pode usar ou ignorar todas as partes do nome do assembly.
Os efeitos de diferentes opções de resolução de assembly são exibidos como uma tabela na seção Resolução de nome misto, para nomes de tipo simples e qualificados para assembly.
Resolver tipos
Se typeName
não especificar um nome de assembly, typeResolver
é sempre chamado. Se typeName
especificar um nome de assembly, typeResolver
será chamado somente quando o nome do assembly for resolvido com êxito. Se assemblyResolver
ou a sondagem de assembly padrão retornar null
, typeResolver
não será chamada.
O typeResolver
método recebe três argumentos:
- O assembly a ser pesquisado ou
null
setypeName
não contém um nome de assembly. - O nome simples do tipo. No caso de um tipo aninhado, este é o tipo de conteúdo mais externo. No caso de um tipo genérico, este é o nome simples do tipo genérico.
- Um valor booleano que é se o caso de
true
nomes de tipo deve ser ignorado.
A implementação determina a maneira como esses argumentos são usados. O typeResolver
método deve retornar null
se não puder resolver o tipo. Se typeResolver
retorna null
e throwOnError
é true
, essa sobrecarga de GetType joga um TypeLoadException.
Os efeitos de diferentes opções de resolução de tipo são exibidos como uma tabela na seção Resolução de nome misto, para nomes de tipo simples e qualificados para assembly.
Resolver tipos aninhados
Se typeName
for um tipo aninhado, somente o nome do tipo que contém o mais externo será passado para typeResolver
. Quando typeResolver
retorna esse tipo, o GetNestedType método é chamado recursivamente até que o tipo aninhado mais interno tenha sido resolvido.
Resolver tipos genéricos
O GetType é chamado recursivamente para resolver tipos genéricos: primeiro para resolver o próprio tipo genérico e, em seguida, para resolver seus argumentos de tipo. Se um argumento de tipo é genérico, GetType é chamado recursivamente para resolver seus argumentos de tipo e assim por diante.
A combinação de assemblyResolver
e typeResolver
que você fornece deve ser capaz de resolver todos os níveis dessa recursão. Por exemplo, suponha que você forneça um assemblyResolver
que controla o carregamento do MyAssembly
. Suponha que você deseja resolver o tipo Dictionary<string, MyType>
genérico (Dictionary(Of String, MyType)
no Visual Basic). Você pode passar o seguinte nome de tipo genérico:
"System.Collections.Generic.Dictionary`2[System.String,[MyNamespace.MyType, MyAssembly]]"
Observe que MyType
esse é o único argumento de tipo qualificado para assembly. Os nomes das Dictionary<TKey,TValue> classes e String não são qualificados para assembly. Você typeResolver
deve ser capaz de lidar com um assembly ou null
, porque ele receberá null
para Dictionary<TKey,TValue> e String. Ele pode lidar com esse caso chamando uma sobrecarga do método que usa uma cadeia de GetType caracteres, porque ambos os nomes de tipo não qualificados estão em 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))
O assemblyResolver
método não é chamado para o tipo de dicionário e o tipo de cadeia de caracteres, porque esses nomes de tipo não são qualificados para assembly.
Agora suponha que, em vez de , o primeiro tipo de System.String
argumento genérico seja YourType
, de YourAssembly
:
"System.Collections.Generic.Dictionary`2[[YourNamespace.YourType, YourAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null], [MyNamespace.MyType, MyAssembly]]"
Como esse assembly não é nem mscorlib.dll/System.Private.CoreLib.dll nem o assembly em execução no momento, você não pode resolver YourType
sem um nome qualificado para assembly. Como você assemblyResolve
será chamado recursivamente, ele deve ser capaz de lidar com esse caso. Em vez de retornar null
para assemblies diferentes do MyAssembly
, ele agora executa uma carga de assembly usando o objeto fornecido 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)
Resolver nomes de tipo com caracteres especiais
Certos caracteres têm significados especiais em nomes qualificados para montagem. Se um nome de tipo simples contiver esses caracteres, os caracteres causarão erros de análise quando o nome simples fizer parte de um nome qualificado para assembly. Para evitar os erros de análise, você deve escapar dos caracteres especiais com uma barra invertida antes de passar o nome qualificado do assembly para o GetType método. Por exemplo, se um tipo for nomeado Strange]Type
, o caractere de escape deverá ser adicionado antes do colchete da seguinte maneira: Strange\]Type
.
Observação
Nomes com esses caracteres especiais não podem ser criados no Visual Basic ou C#, mas podem ser criados usando CIL (linguagem intermediária comum) ou emitindo assemblies dinâmicos.
A tabela a seguir mostra os caracteres especiais para nomes de tipo.
Caractere | Significado |
---|---|
, (vírgula) |
Delimitador para nomes qualificados para assembly. |
[] (colchetes) |
Como um par de sufixos, indica um tipo de matriz; como um par delimitador, inclui listas de argumentos genéricos e nomes qualificados para assembly. |
& (e comercial) |
Como sufixo, indica que um tipo é um tipo de referência. |
* (asterisco) |
Como sufixo, indica que um tipo é um tipo de ponteiro. |
+ (mais) |
Delimitador para tipos aninhados. |
\ (barra invertida) |
Caractere de escape. |
Propriedades como AssemblyQualifiedName retornar sequências de caracteres escapadas corretamente. Você deve passar corretamente sequências de caracteres escapadas para o GetType método. Por sua vez, o GetType método passa corretamente nomes escapados para typeResolver
e para os métodos de resolução de tipo padrão. Se você precisar comparar um nome com um nome sem escape no typeResolver
, deverá remover os caracteres de escape.
Resolução de nomes mistos
A tabela a seguir resume as interações entre assemblyResolver
, typeResolver
e a resolução de nome padrão, para todas as combinações de nome de tipo e nome de assembly em typeName
:
Conteúdo do nome do tipo | Método do resolvedor de montagem | Método do resolvedor de tipos | Resultado |
---|---|---|---|
tipo, assembly | nulo | nulo | Equivalente a chamar a sobrecarga do Type.GetType(String, Boolean, Boolean) método. |
tipo, assembly | fornecido | nulo | assemblyResolver retorna o assembly ou retorna null se ele não puder resolver o assembly. Se o assembly for resolvido, a Assembly.GetType(String, Boolean, Boolean) sobrecarga de método será usada para carregar o tipo do assembly, caso contrário, não haverá nenhuma tentativa de resolver o tipo. |
tipo, assembly | nulo | fornecido | Equivalente a converter o nome do assembly em um AssemblyName objeto e chamar a sobrecarga do Assembly.Load(AssemblyName) método para obter o assembly. Se o assembly for resolvido, ele será passado para typeResolver ; caso contrário, typeResolver não é chamado e não há mais nenhuma tentativa de resolver o tipo. |
tipo, assembly | fornecido | fornecido | assemblyResolver retorna o assembly ou retorna null se ele não puder resolver o assembly. Se o assembly for resolvido, ele será passado para typeResolver ; caso contrário, typeResolver não é chamado e não há mais nenhuma tentativa de resolver o tipo. |
tipo | nulo, fornecido | nulo | Equivalente a chamar a sobrecarga do Type.GetType(String, Boolean, Boolean) método. Como o nome do assembly não é fornecido, somente mscorlib.dll/System.Private.CoreLib.dll e o assembly em execução no momento são pesquisados. Se assemblyResolver for fornecido, é ignorado. |
tipo | nulo, fornecido | fornecido | typeResolver é chamado, e null é aprovado para a assembleia. typeResolver pode fornecer um tipo de qualquer montagem, incluindo montagens que ele carrega para a finalidade. Se assemblyResolver for fornecido, é ignorado. |
assembly | nulo, fornecido | nulo, fornecido | A FileLoadException é lançado, porque o nome do assembly é analisado como se fosse um nome de tipo qualificado para assembly. Isso resulta em um nome de assembly inválido. |