2008-10-07 20 views
31

Quiero obtener un System.Type dado solo el nombre del tipo en un string.Obtener un System.Type del nombre parcial del tipo

Por ejemplo, si tengo un objeto:

MyClass abc = new MyClass(); 

Entonces se puede decir:

System.Type type = abc.GetType(); 

Pero lo que si todo lo que tengo es:

string className = "MyClass"; 
+0

posible duplicado de [Evite dar nombre del espacio de nombres en Type.GetType()] (http: // stackoverflow .com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) – Fr33dan

+0

@ Fr33dan, Circular loop? El mencionado posible [original] (http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type-gettype) menciona [esta pregunta] (http://stackoverflow.com/questions/179102/getting-a-system-type-from-types-partial-name) como posible original (ver [comentario] (http://stackoverflow.com/questions/9273629/avoid-giving-namespace-name-in-type- gettype # comment39575691_9273629))? :) – publicgk

+0

@publicgk En realidad estaba tratando de marcarlo para una fusión con esa pregunta ya que son los mismos pero esa pregunta y ambas tienen buenas respuestas. Ver [esta meta pregunta] (http://meta.stackoverflow.com/q/269080/1111886). Al parecer lo hice mal y me rendí, luego alguien entró más tarde y decidió que este era el duplicado ya que la otra era una pregunta anterior. – Fr33dan

Respuesta

33
Type type = Type.GetType("foo.bar.MyClass, foo.bar"); 

MSDN. Asegúrese de que el nombre sea Assembly Qualified.

+1

Una nota importante: requiere el nombre de tipo completo. – leppie

2
Type type = Type.GetType("MyClass"); 

Asegúrese de incluir el espacio de nombres. Hay sobrecargas del método que controla la sensibilidad a mayúsculas y minúsculas y si se lanza una excepción si no se encuentra el nombre del tipo.

+1

Incorrecto, también debe especificar el ensamblaje. –

+2

Eso no funcionará :) – leppie

+1

De los documentos, "Si el tipo está en el ensamblado que se está ejecutando actualmente o en Mscorlib.dll, es suficiente proporcionar el nombre de tipo calificado por su espacio de nombres". – jalbert

2

para crear una instancia de la clase después de obtener el tipo, e invocar un método -

Type type = Type.GetType("foo.bar.MyClass, foo.bar"); 
object instanceObject = System.Reflection.Activator.CreateInstance(type); 
type.InvokeMember(method, BindingFlags.InvokeMethod, null, instanceObject, new object[0]); 
0

Type.GetType(...) puede fallar a veces, si el operador typeof no se puede utilizar.

En su lugar, puede reflejar los ensamblados del dominio actual para poder hacerlo.

comprobar mi respuesta en this thread

1

Otra forma de obtener el tipo de corriente u otra assebly.

(asume que el espacio de nombres de clase contiene su montaje):


public static Type GetType(string fullName) 
{ 
    if (string.IsNullOrEmpty(fullName)) 
     return null; 
    Type type = Type.GetType(fullName); 
    if (type == null) 
    { 
     string targetAssembly = fullName; 
     while (type == null && targetAssembly.Length > 0) 
     { 
      try 
      { 
       int dotInd = targetAssembly.LastIndexOf('.'); 
       targetAssembly = dotInd >= 0 ? targetAssembly.Substring(0, dotInd) : ""; 
       if (targetAssembly.Length > 0) 
        type = Type.GetType(fullName + ", " + targetAssembly); 
      } 
      catch { } 
     } 
    } 
    return type; 
} 
0

Aquí es un método simple para crear e inicializar un nuevo objeto a partir de su nombre y parámetros:

// Creates and initializes a new object from its name and parameters 
    public Object CreateObjectByName(string name, params Object[] args) 
    { 
     string s = "<prefix>" + name; // case sensitive; Type.FullName 
     Type type = Type.GetType(s); 
     Object o = System.Activator.CreateInstance(type, args); 
     return o; 
    } 

Un ejemplo de cómo se podría usar esto es leer un archivo que contenga nombres de clase [o nombres de clase parciales] y parámetros y luego agregar los objetos devueltos a una lista de objetos de un tipo base que sea commo. n a los objetos creados.

Para ver lo que su nombre de la clase [o] debe ser similar, utilizar temporalmente algo como esto [si su clase se llama NewClass]:

string z = (new NewClass(args)).GetType().FullName; 
33

Depende de la que el conjunto de la clase es.Si está en mscorlib o llamando al montaje de todo lo que necesita es

Type type = Type.GetType("namespace.class"); 

Pero si se hace referencia desde algún otro montaje, lo que tendría que hacer:

Assembly assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
Type type = assembly.GetType("namespace.class"); 

//or 

Type type = Type.GetType("namespace.class, assembly"); 

Si sólo tiene el nombre de clase "MyClass", entonces debe obtener de alguna manera el nombre del espacio de nombres (o el nombre del espacio de nombres y el nombre del ensamblado en caso de que se trate de un ensamblaje al que se hace referencia) y concat junto con el nombre de la clase. Algo así como:

//if class is in same assembly 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = Type.GetType(namespace + "." + "MyClass"); 


//or for cases of referenced classes 
var assembly = typeof(SomeKnownTypeInAssembly).Assembly; 
var namespace = typeof(SomeKnownTypeInNamespace).Namespace; 
Type type = assembly.GetType(namespace + "." + "MyClass"); 
//or 
Type type = Type.GetType(namespace + "." + "MyClass" + ", " + assembly.GetName().Name); 

Si usted no tiene absolutamente nada (sin preawareness incluso de nombre de ensamblado o el nombre de espacio de nombres), pero sólo el nombre de la clase, a continuación, se puede consultar la totalidad de las asambleas para seleccionar una cadena coincidente. Pero eso debería ser mucho más lento:

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .SelectMany(x => x.GetTypes()) 
            .FirstOrDefault(x => x.Name == "MyClass"); 

Tenga en cuenta que esto devuelve la primera clase de juego, por lo que no tiene que ser muy preciso si desea tener varias clases con el mismo nombre a través de ensambles/espacios de nombres. En cualquier caso, el almacenamiento en caché de los valores tiene sentido aquí. manera un poco más rápido es asumir que hay un espacio de nombres por defecto:

Type type = AppDomain.CurrentDomain.GetAssemblies() 
            .Select(a => new { a, a.GetTypes().First().Namespace }) 
            .Select(x => x.a.GetType(x.Namespace + "." + "MyClass")) 
            .FirstOrDefault(x => x != null); 

Pero eso es otra vez una suposición de que el tipo tendrá el mismo espacio de nombres que alguna otra clase al azar en la asamblea; demasiado quebradizo, no muy bueno.


Si desea clases de otros dominios, usted puede obtener una lista de todos los dominios de aplicación, siguiendo this link. A continuación, puede hacer lo mismo de consulta como se muestra arriba para cada dominio. Si su ensamblaje donde reside el tipo no está cargado aún, entonces tiene que cargarlo manualmente usando Assembly.Load, Assembly.LoadFrom etc.

Cuestiones relacionadas