net - reflection c# español
Obtener un System.Type del nombre parcial del tipo (7)
Aquí hay 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 puede 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 es común a los objetos creados.
Para ver cómo debería ser tu nombre de clase [o], utiliza temporalmente algo como esto [si tu clase se llama NewClass]:
string z = (new NewClass(args)).GetType().FullName;
Quiero obtener un System.Type
dado solo el nombre de tipo en una string
.
Por ejemplo, si tengo un objeto:
MyClass abc = new MyClass();
Entonces puedo decir:
System.Type type = abc.GetType();
Pero qué pasa si todo lo que tengo es:
string className = "MyClass";
Depende del ensamblaje de la clase. Si está en mscorlib
o ensamblado de llamadas, todo lo que necesita es
Type type = Type.GetType("namespace.class");
Pero si se hace referencia a partir de algún otro ensamblaje, tendría que hacer:
Assembly assembly = typeof(SomeKnownTypeInAssembly).Assembly;
Type type = assembly.GetType("namespace.class");
//or
Type type = Type.GetType("namespace.class, assembly");
Si solo tiene el nombre de clase "MyClass", 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 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 no tiene absolutamente nada (ni conocimiento de siquiera el nombre del ensamblado o el nombre del espacio de nombres), sino solo el nombre de la clase, puede consultar los ensamblajes completos 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 coincidente, por lo que no es necesario que sea muy preciso si tuviera varias clases con el mismo nombre en ensamblados / espacios de nombres. En cualquier caso, el almacenamiento en caché de los valores tiene sentido aquí. Una forma ligeramente más rápida es suponer que hay un espacio de nombre predeterminado :
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 una suposición de que su tipo tendrá el mismo espacio de nombres que cualquier otra clase aleatoria en el ensamblado; demasiado quebradizo, no muy bueno.
Si desea clases de otros dominios, puede obtener una lista de todos los dominios de la aplicación, siguiendo este enlace. A continuación, puede hacer la misma consulta que se muestra arriba para cada dominio. Si su ensamblaje donde reside el tipo no está cargado aún, entonces debe cargarlo manualmente usando Assembly.Load
, Assembly.LoadFrom
, etc.
Otra forma de obtener el tipo de corriente u otra asesebly.
(Supone que el espacio de nombres de clase contiene su ensamblaje):
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;
}
Para crear una instancia de su 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]);
Type.GetType(...)
puede fallar a veces si no se puede usar el operador typeof
.
En su lugar, puede reflexionar sobre los ensamblados del dominio actual para hacerlo.
revisa mi respuesta en este hilo
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.
Type type = Type.GetType("foo.bar.MyClass, foo.bar");
MSDN . Asegúrese de que el nombre sea Ensamblado Calificado .