.net - tipo - type integer c#
¿Cómo funciona Type.GetType cuando se le da un nombre de tipo parcialmente calificado? (5)
El código que trabaja con la forma corta es:
Assembly a = Assembly.LoadWithPartialName(assemblyName);
Type t = a.GetType(typeName);
pero LoadWithPartialName está en desuso, así que supongo que deberías apegarte a la forma larga.
En muchos lugares me encuentro con nombres de tipo parcialmente calificados de la forma FullTypeName, AssemblyName
, es decir, como Type.AssemblyQualifiedName
solo sin los calificadores de versión, cultura y publicKeyToken.
Mi pregunta es ¿cómo se puede convertir uno al Type
respectivo en un esfuerzo mínimo? Pensé que Type.GetType
hace el trabajo, pero, por desgracia, no lo hace. El siguiente código, por ejemplo, devuelve null
:
Type.GetType("System.Net.Sockets.SocketException, System");
Por supuesto, si especifico el nombre completo, sí funciona:
Type.GetType("System.Net.Sockets.SocketException, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089");
Muchas gracias.
Es cierto que Type.GetType (cadena) requiere un AssemblyQualifiedName. Esto puede ser en muchas formas:
MyNS.MyType, MyAssembly, Version=x.x.x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX
Los siguientes también son AssemblyQualifiedNames válidos:
MyNS.MyType, MyAssembly, Version=x.x, Culture=xxx, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly, Culture=xxx, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX
MyNS.MyType, MyAssembly
Para un ensamblaje firmado, el mínimo requerido para un FullyQualifiedAssemblyName es:
MyNS.MyType, MyAssembly, PublicKeyToken=XXXXXXXXXX
Para un ensamblaje sin firma, el mínimo requerido para un FullyQualifiedAssemblyName es:
MyNS.MyType, MyAssembly
No es necesario que todos los "códigos de la mano" que aparecen en los fragmentos de código que otros han proporcionado. Asegúrese de que los nombres de los tipos estén configurados correctamente y que pueda acceder a sus tipos (y cargar ensamblajes dinámicamente) con un alto grado de flexibilidad. Hago esto regularmente.
En el ejemplo de OP usando:
Type.GetType("System.Net.Sockets.SocketException, System")
El motivo del fallo fue la ausencia de PublicKeyToken. Los ensamblados .Net FW están todos firmados y, por lo tanto, requieren que PublicKeyToken resuelva el nombre del ensamblado. Lo siguiente funcionaría:
Type.GetType("System.Net.Sockets.SocketException, System, PublicKeyToken=b77a5c561934e089")
Habiendo pasado por un problema similar con algún código heredado, no creo que la primera afirmación en la respuesta aceptada sea correcta. No importa si el ensamblaje ya está cargado.
De acuerdo con la documentación, Type.GetType(string) requiere un AssemblyQualifiedName , a menos que el tipo en cuestión esté en el ensamblado que se está ejecutando actualmente o en mscorlib, en cuyo caso el nombre del tipo calificado con espacio de nombres es todo lo que se requiere.
Tenga en cuenta que un AssemblyQualifiedName incluye el DisplayName completo del ensamblado del tipo (con la versión, la cultura y el token de clave pública).
La versión corta no funcionará a menos que intercepte la carga de tipo fallida con un Resolvedor de AssemblyResolver personalizado (que en realidad fue el caso con mi problema, que enmascara otro problema).
Si el ensamblaje se ha cargado en el dominio actual, el siguiente código generalmente funciona:
public static Type GetTypeEx(string fullTypeName)
{
return Type.GetType(fullTypeName) ??
AppDomain.CurrentDomain.GetAssemblies()
.Select(a => a.GetType(fullTypeName))
.FirstOrDefault(t => t != null);
}
Puedes usarlo así:
Type t = GetTypeEx("System.Net.Sockets.SocketException");
Si la DLL en la que se encuentra no está ya cargada en el dominio de la aplicación (por ejemplo, la usó), necesita la ruta completa como esta, si ya está cargada, puede encontrarla con la versión más corta.
Para responder a tu pregunta: la segunda versión siempre funciona, apégate a ella y tienes una forma de preocuparte.