2009-09-08 16 views
12

Estoy tratando de obtener un objeto Tipo de Tipo de nombre completo que estoy haciendo el folowing:Creación de C# Tipo de nombre completo

Assembly asm = Assembly.GetEntryAssembly(); 
string toNativeTypeName="any type full name"; 
Type t = asm.GetType(toNativeTypeName); 

consigo nula, ¿por qué?

la asamblea es mi ejecutable (.NET ejecutable) y el nombre del tipo es: System.Xml.XmlNode

+0

Muéstranos lo que quieres decir con un nombre completo? – AnthonyWJones

+0

el ensamblado es mi ejecutable (ejecutable .net) y el nombre de tipo es: System.Xml.XmlNode –

+0

System.Xml.XmlNode no existirá en su ensamblado, por lo que debe usar Type.GetType inestead of Assembly.GetType. –

Respuesta

27

Bueno, si es que realmente el nombre completo del tipo (es decir, incluyendo espacio de nombres) y es en esa asamblea, entonces debería funcionar. ¿Podría dar un ejemplo donde no? Como está usando Assembly.GetType en lugar de Type.GetType, no debe incluir el nombre del ensamblado en el nombre del tipo.

Tenga en cuenta que el nombre para un tipo genérico no es lo que usted podría esperar. Por ejemplo, tendrá que utilizar:

assembly.GetType("System.Collections.Generic.List`1"); 

para obtener el tipo de lista genérica, a continuación, utilizar Type.MakeGenericType para proporcionar argumentos de tipo.

Por supuesto, eso solo es relevante cuando el tipo es genérico. Si ese no es el problema, verificaría que el tipo realmente esté en tu ensamblaje de entrada.

EDIT: Ah, y ser conscientes de que los tipos anidados serán "Contenedor + anidado" en lugar de "Container.Nested" si eso es relevante ...

+0

el ensamblado es mi ejecutable (ejecutable .net) y el nombre del tipo es: System.Xml.XmlNode –

+4

Entonces ese es el problema: System.Xml.XmlNode no es un tipo dentro de su ensamblaje, ¿o sí? Tendrá que usar el ensamblaje adecuado o llamar a Type.GetType con la información de ensamblaje completa. –

+0

+1 Mucha información buena aquí. –

4

Su nombre tipo es el más probablemente equivocado. Si crea una referencia al tipo en el código y luego verifica su propiedad Type.FullName, verá cómo debería verse el nombre del tipo.

También podría probar el método Type.GetType y ver qué devuelve. Tal vez su tipo no está en esa asamblea en absoluto?

Editar: Resulta que estaba equivocado sobre el uso de la propiedad Type.FullName. Si usa la propiedad Type.AssemblyQualifiedName obtendrá el nombre completamente calificado que Type.GetType puede usar.

Para System.Xml.XmlNode se obtiene el siguiente nombre: System.Xml.XmlElement, System.Xml, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

6

razón por la que está definiendo el montaje de usar solicitud Tipo !, también hay que poner espacio de nombres

string toNativeTypeName = "System.Int32"; 
Type t = Type.GetType(toNativeTypeName); 
MessageBox.Show(t.FullName); 
+3

Si sabe que el tipo * es * en el ensamblado de entrada, entonces usando Assembly.GetType con el nombre incluido el espacio de nombres pero * no * el nombre del ensamblado puede ser mucho más fácil que incluir el nombre completo del ensamblado, incluida la versión ... –

+0

Esto me ayudó. Estaba tratando de sacar los mensajes serializados de una cola. Estuve probando con System.String y no lo encontré mientras recorría todos los ensamblajes del dominio actual. Cuando cambio para usar Type.GetType, simplemente funcionó. Gracias por el consejo. – fizch

3

me encontré con este hilo y notó que la pregunta original no ha sido respondida del todo. Podría estar equivocado, pero al leer la pregunta, creo que la intención de los autores fue poder obtener simplemente un Tipo de una Asamblea a la que se hace referencia o como parte de su aplicación.

Esto es lo que hice para resolver ese problema.

public static Type GetTypeFromFullName(string fullClassName) 
{ 
    AssemblyPartCollection parts = Deployment.Current.Parts; 

    foreach (var part in parts) 
    { 
     Uri resUri = new Uri(part.Source, UriKind.Relative); 
     Stream resStream = Application.GetResourceStream(resUri).Stream; 
     Assembly resAssembly = part.Load(resStream); 
     Type tryType = resAssembly.GetType(fullClassName, false); 
     if (tryType != null) 
      return tryType; 
    } 

    return null; 
} 
8

Ver mi sugerencia a continuación, sólo el bucle espacio de nombres de negocios para la velocidad

private static Type GetBusinessEntityType(string typeName) 
{ 
    Debug.Assert(typeName != null); 

    List<System.Reflection.Assembly> assemblies = AppDomain.CurrentDomain.GetAssemblies() 
     .Where(a => a.FullName.StartsWith("AF.BusinessEntities")).ToList(); 

    foreach (var assembly in assemblies) 
    { 
     Type t = assembly.GetType(typeName, false); 
     if (t != null) 
      return t; 
    } 
    throw new ArgumentException(
     "Type " + typeName + " doesn't exist in the current app domain"); 
} 

Ésta es otra manera de hacerlo:

Type t = System.Web.Compilation.BuildManager.GetType("the.type", true, false); 

Uso del reflector para ver cómo se hace, por lo menos para diversión :)

+1

El 'System.Web.Compilation.BuildManager' lo hizo por mí, el otro no lo conseguí para un Enum: 'NLibrary + Modules' – Niels

Cuestiones relacionadas