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
otypeResolver
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 otypeResolver
, el valor delthrowOnError
parámetro se pasa a los métodos que realizan la resolución predeterminada.Si
throwOnError
estrue
, este método produce un TypeLoadException valor whentypeResolver
devuelvenull
y un FileNotFoundException valor whenassemblyResolver
devuelvenull
.Este método no detecta excepciones producidas por
assemblyResolver
ytypeResolver
. 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
sitypeName
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.String
argumento 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 MyAssembly
de , 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
, typeResolver
y 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 typeResolver y 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 typeResolver y 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. |