Métodos System.Type.GetType

En este artículo se proporcionan comentarios adicionales a la documentación de referencia de esta API.

Use la sobrecarga del GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean, Boolean) método y sus sobrecargas asociadas (GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>) y GetType(String, Func<AssemblyName,Assembly>, Func<Assembly,String,Boolean,Type>, Boolean)) para reemplazar la implementación predeterminada del GetType método por implementaciones más flexibles. Al proporcionar sus propios métodos que resuelven los nombres de tipo y los nombres de los ensamblados que los contienen, puede hacer lo siguiente:

  • Controlar desde qué versión de un ensamblado se carga un tipo.
  • Proporcione otro lugar para buscar un nombre de tipo que no incluya un nombre de ensamblado.
  • Cargar ensamblados mediante nombres de ensamblado parcial.
  • Devuelve subclases de System.Type que common Language Runtime (CLR) no crea.

Por ejemplo, en la serialización tolerante a versiones, este método permite buscar un ensamblado de "mejor ajuste" mediante un nombre parcial. Otras sobrecargas del GetType método requieren un nombre de tipo calificado para ensamblados, que incluye el número de versión.

Es posible que las implementaciones alternativas del sistema de tipos necesiten devolver subclases de System.Type que clR no crea; todos los tipos devueltos por otras sobrecargas del GetType método son tipos en tiempo de ejecución.

Notas de uso

Esta sobrecarga del método y sus sobrecargas asociadas analizan typeName en el nombre de un tipo y el nombre de un ensamblado y, a continuación, resuelven los nombres. La resolución del nombre del ensamblado se produce antes de la resolución del nombre de tipo, ya que un nombre de tipo debe resolverse en el contexto de un ensamblado.

Nota:

Si no está familiarizado con el concepto de nombres de tipo calificado para ensamblados, consulte la AssemblyQualifiedName propiedad .

Si typeName no es un nombre completo para ensamblados, se omite la resolución de ensamblados. Los nombres de tipo no calificados se pueden resolver en el contexto de mscorlib.dll/System.Private.CoreLib.dll o el ensamblado que se está ejecutando actualmente, o puede proporcionar opcionalmente un ensamblado en el typeResolver parámetro . Los efectos de incluir o omitir el nombre del ensamblado para diferentes tipos de resolución de nombres se muestran como una tabla en la sección Resolución de nombres mixtos.

Notas de uso general:

  • No pase métodos a assemblyResolver o typeResolver si proceden de autores de llamadas desconocidos o que no son de confianza. Use solo los métodos que proporciona o con los que está familiarizado.

    Precaución

    El uso de métodos de llamadores desconocidos o que no son de confianza podría dar lugar a la elevación de privilegios para código malintencionado.

  • Si omite los assemblyResolver parámetros o typeResolver , el valor del throwOnError parámetro se pasa a los métodos que realizan la resolución predeterminada.

  • Si throwOnError es true, este método produce un TypeLoadException valor when typeResolver devuelve nully un FileNotFoundException valor when assemblyResolver devuelve null.

  • Este método no detecta excepciones producidas por assemblyResolver y typeResolver. Usted es responsable de las excepciones producidas por los métodos de resolución.

Resolución de ensamblados

El assemblyResolver método recibe un AssemblyName objeto , que se genera mediante el análisis del nombre del ensamblado de cadena que se incluye en typeName. Si typeName no contiene un nombre de ensamblado, assemblyResolver no se llama a y null se pasa a typeResolver.

Si assemblyResolver no se proporciona, el sondeo de ensamblado estándar se usa para localizar el ensamblado. Si assemblyResolver se proporciona, el GetType método no realiza sondeos estándar; en ese caso, debe asegurarse de que assemblyResolver puede controlar todos los ensamblados que se le pasan.

El assemblyResolver método debe devolver null si no se puede resolver el ensamblado. Si assemblyResolver devuelve null, typeResolver no se llama a y no se produce ningún procesamiento adicional; además, si throwOnError es true, se produce una FileNotFoundException excepción .

Si el AssemblyName que se pasa a assemblyResolver es un nombre parcial, uno o varios de sus elementos son null. Por ejemplo, si no tiene ninguna versión, la Version propiedad es null. Si la Version propiedad , la CultureInfo propiedad y el GetPublicKeyToken método devuelven null, solo se proporcionó el nombre simple del ensamblado. El assemblyResolver método puede usar o omitir todas las partes del nombre del ensamblado.

Los efectos de diferentes opciones de resolución de ensamblados se muestran como una tabla en la sección Resolución de nombres mixtos, para nombres de tipo simples y calificados para ensamblados.

Resolución de tipos

Si typeName no especifica un nombre de ensamblado, typeResolver siempre se llama a . Si typeName especifica un nombre de ensamblado, typeResolver solo se llama cuando el nombre del ensamblado se resuelve correctamente. Si assemblyResolver o el sondeo de ensamblado estándar devuelve null, typeResolver no se llama a .

El typeResolver método recibe tres argumentos:

  • Ensamblado que se va a buscar o null si typeName no contiene un nombre de ensamblado.
  • Nombre simple del tipo. En el caso de un tipo anidado, este es el tipo contenedor más externo. En el caso de un tipo genérico, este es el nombre simple del tipo genérico.
  • Valor booleano que es true si se omitirán las mayúsculas y minúsculas de los nombres de tipo.

La implementación determina la forma en que se usan estos argumentos. El typeResolver método debe devolver null si no puede resolver el tipo. Si typeResolver devuelve null y throwOnError es true, esta sobrecarga de GetType produce una TypeLoadExceptionexcepción .

Los efectos de diferentes opciones de resolución de tipos se muestran como una tabla en la sección Resolución de nombres mixtos para nombres de tipo simples y calificados para ensamblados.

Resolución de tipos anidados

Si typeName es un tipo anidado, solo se pasa el nombre del tipo contenedor más externo a typeResolver. Cuando typeResolver devuelve este tipo, se GetNestedType llama al método de forma recursiva hasta que se ha resuelto el tipo anidado más interno.

Resolución de tipos genéricos

GetType Se llama de forma recursiva para resolver tipos genéricos: primero para resolver el propio tipo genérico y, a continuación, para resolver sus argumentos de tipo. Si un argumento de tipo es genérico, GetType se denomina recursivamente para resolver sus argumentos de tipo, etc.

La combinación de assemblyResolver y typeResolver que proporciona debe ser capaz de resolver todos los niveles de esta recursividad. Por ejemplo, supongamos que proporciona un assemblyResolver que controla la carga de MyAssembly. Supongamos que desea resolver el tipo Dictionary<string, MyType> genérico (Dictionary(Of String, MyType) en Visual Basic). Puede pasar el siguiente nombre de tipo genérico:

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

Observe que MyType es el único argumento de tipo calificado para ensamblados. Los nombres de las Dictionary<TKey,TValue> clases y String no están calificados para ensamblados. typeResolver Debe ser capaz de controlar un ensamblado o null, ya que recibirá null para Dictionary<TKey,TValue> y String. Puede controlar ese caso llamando a una sobrecarga del GetType método que toma una cadena, ya que ambos nombres de tipo no calificado están en 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))

No assemblyResolver se llama al método para el tipo de diccionario y el tipo de cadena, porque esos nombres de tipo no están calificados para ensamblados.

Ahora supongamos que, en lugar de , el primer tipo de System.Stringargumento genérico es YourType, de YourAssembly:

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

Dado que este ensamblado no es mscorlib.dll/System.Private.CoreLib.dll ni el ensamblado que se está ejecutando actualmente, no se puede resolver YourType sin un nombre completo para ensamblados. assemblyResolve Dado que se llamará de forma recursiva, debe ser capaz de controlar este caso. En lugar de devolver null para ensamblados distintos MyAssemblyde , ahora realiza una carga de ensamblado mediante el objeto proporcionado 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)

Resolución de nombres de tipo con caracteres especiales

Algunos caracteres tienen significados especiales en nombres calificados para ensamblados. Si un nombre de tipo simple contiene estos caracteres, los caracteres provocan errores de análisis cuando el nombre simple forma parte de un nombre calificado por ensamblados. Para evitar los errores de análisis, debe escapar los caracteres especiales con una barra diagonal inversa para poder pasar el nombre completo del ensamblado al GetType método . Por ejemplo, si un tipo se denomina Strange]Type, el carácter de escape debe agregarse delante del corchete como se indica a continuación: Strange\]Type.

Nota:

Los nombres con estos caracteres especiales no se pueden crear en Visual Basic o C#, pero se pueden crear mediante lenguaje intermedio común (CIL) o mediante la emisión de ensamblados dinámicos.

En la tabla siguiente se muestran los caracteres especiales para los nombres de tipo.

Carácter Significado
, (coma) Delimitador para nombres calificados para ensamblados.
[] (corchetes) Como par de sufijos, indica un tipo de matriz; como par de delimitador, incluye listas de argumentos genéricos y nombres calificados para ensamblados.
& ("Y comercial") Como sufijo, indica que un tipo es un tipo de referencia.
* (asterisco) Como sufijo, indica que un tipo es un tipo de puntero.
+ (más) Delimitador para tipos anidados.
\ (barra diagonal inversa) Carácter de escape.

Propiedades como AssemblyQualifiedName devolver cadenas con escape correctamente. Debe pasar correctamente cadenas de escape al GetType método . A su vez, el GetType método pasa los nombres con escape correctos a typeResolver los métodos de resolución de tipos predeterminados y a los métodos de resolución de tipos predeterminados. Si necesita comparar un nombre con un nombre sin escape en typeResolver, debe quitar los caracteres de escape.

Resolución de nombres mixtos

En la tabla siguiente se resumen las interacciones entre assemblyResolver, typeResolvery la resolución de nombres predeterminada, para todas las combinaciones de nombre de tipo y nombre de ensamblado en typeName:

Contenido del nombre de tipo Método de resolución de ensamblados Método de resolución de tipos Resultado
type, assembly nulo nulo Equivalente a llamar a la sobrecarga del Type.GetType(String, Boolean, Boolean) método.
type, assembly proporcionado nulo assemblyResolver devuelve el ensamblado o devuelve null si no puede resolver el ensamblado. Si se resuelve el ensamblado, la Assembly.GetType(String, Boolean, Boolean) sobrecarga del método se usa para cargar el tipo desde el ensamblado; de lo contrario, no hay ningún intento de resolver el tipo.
type, assembly nulo proporcionado Equivalente a convertir el nombre del ensamblado en un AssemblyName objeto y llamar a la sobrecarga del Assembly.Load(AssemblyName) método para obtener el ensamblado. Si se resuelve el ensamblado, se pasa a ; de lo contrario, typeResolver no se llama a typeResolvery no se intenta resolver el tipo.
type, assembly proporcionado proporcionado assemblyResolver devuelve el ensamblado o devuelve null si no puede resolver el ensamblado. Si se resuelve el ensamblado, se pasa a ; de lo contrario, typeResolver no se llama a typeResolvery no se intenta resolver el tipo.
type null, proporcionado nulo Equivalente a llamar a la sobrecarga del Type.GetType(String, Boolean, Boolean) método. Dado que no se proporciona el nombre del ensamblado, solo se busca mscorlib.dll/System.Private.CoreLib.dll y el ensamblado que se está ejecutando actualmente. Si assemblyResolver se proporciona, se omite.
type null, proporcionado proporcionado typeResolver se llama a y null se pasa para el ensamblado. typeResolver puede proporcionar un tipo desde cualquier ensamblado, incluidos los ensamblados que carga para el propósito. Si assemblyResolver se proporciona, se omite.
ensamblado null, proporcionado null, proporcionado FileLoadException Se produce una excepción porque el nombre del ensamblado se analiza como si fuera un nombre de tipo calificado para ensamblados. Esto da como resultado un nombre de ensamblado no válido.