Compartilhar via


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 ou typeResolver 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/ou typeResolver , o throwOnError valor do parâmetro será passado para os métodos que executam a resolução padrão.

  • Se throwOnError for true, esse método lança um TypeLoadException quando typeResolver retorna nulle um FileNotFoundException quando assemblyResolver retorna null.

  • Esse método não captura exceções lançadas por assemblyResolver e typeResolver. 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 se typeName 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.Stringargumento 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, typeResolvere 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.