2011-12-14 18 views
30

Tengo un programa C#, ¿cómo puedo verificar en tiempo de ejecución si existe un espacio de nombre, clase o método? Además, ¿cómo instanciar una clase usando su nombre en forma de cadena?C# - ¿Cómo comprobar si existe espacio de nombres, clase o método en C#?

Pseudocódigo:

string @namespace = "MyNameSpace"; 
string @class = "MyClass"; 
string method= "MyMEthod"; 

var y = IsNamespaceExists(namespace); 
var x = IsClassExists(@class)? new @class : null; //Check if exists, instantiate if so. 
var z = x.IsMethodExists(method); 
+0

Por favor, recuerde que debe marcar la respuesta más apropiada como respuesta. –

Respuesta

39

Puede utilizar Type.GetType(string) para reflejar una clase. Type tiene métodos para descubrir otros miembros, incluido un método, que están disponibles para ese tipo.

Un truco, sin embargo, es que GetType quiere un nombre calificado como ensamblador. Si usa solo el nombre de la clase en sí, asumirá que está haciendo referencia al ensamblado actual.

Por lo tanto, si usted quiere encontrar el tipo en todos los ensamblados cargados, se puede hacer algo como esto (usando LINQ):

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
      from type in assembly.GetTypes() 
      where type.Name == className 
      select type); 

Por supuesto, puede haber más que eso, donde Querrá reflejar los ensamblajes a los que se hace referencia que aún no se pueden cargar, etc.

En cuanto a la determinación de los espacios de nombres, la reflexión no los exporta claramente. En su lugar, habría que hacer algo como:

var namespaceFound = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
from type in assembly.GetTypes() 
where type.Namespace == namespace 
select type).Any() 

Poniendo todo junto, usted tendría algo como:

var type = (from assembly in AppDomain.CurrentDomain.GetAssemblies() 
       from type in assembly.GetTypes() 
       where type.Name == className && type.GetMethods().Any(m => m.Name == methodName) 
       select type).FirstOrDefault(); 

if (type == null) throw new InvalidOperationException("Valid type not found."); 

object instance = Activator.CreateInstance(type); 
+2

¿Y cómo determinaría si existe un espacio de nombres con sus ejemplos? –

+0

Actualizado mi respuesta. Verifica el segundo ejemplo de código. Enumeramos cada ensamblaje cargado, y cada tipo en cada ensamblaje, y buscamos cualquier tipo que tenga el nombre de espacio de nombres deseado. – HackedByChinese

+1

Si desea comprobar que el espacio de nombres es válido, el nombre de clase es válido y la clase tiene un método, puede hacerlo todo de una vez con el tercer ejemplo de código. simplemente cambie donde type.Name == className a algo como 'where type.FullName == string.Format (" {0}. {1} ", namespace, className) && type.GetMethods(). Any (m => m .Name == methodName) '. Además, cometí un error en esos ejemplos al omitir la parte 'select' de la declaración. corregido – HackedByChinese

2

Una palabra: Reflection. A excepción de los espacios de nombres, tendrá que analizarlos con los nombres de Tipo.

EDIT: Ataque que: para los espacios de nombres, deberá usar la propiedad Type.Namespace para determinar a qué espacio de nombres pertenece cada clase. (Ver HackedByChinese response para más información).

+0

+1 ¡Gracias! La reflexión parece interesante. – dpp

25

Puede resolver un Type desde una cadena utilizando el método Type.GetType(String). Por ejemplo:

Type myType = Type.GetType("MyNamespace.MyClass"); 

A continuación, puede utilizar este tipo de instancia para comprobar si existe un método del tipo llamando al método GetMethod(String). Por ejemplo:

MethodInfo myMethod = myType.GetMethod("MyMethod"); 

Tanto GetType y GetMethod vuelven null Si no se encontró ningún tipo o método para el nombre dado, para que pueda comprobar si su tipo/método existe comprobando si su llamada al método devuelve nulo o no.

Por último, se puede crear una instancia de su tipo usando Activator.CreateInstance(Type) Por ejemplo:

object instance = Activator.CreateInstance(myType); 
+1

Esta es una respuesta mucho más rápida y concisa que la marcada como correcta arriba. Girar cada tipo en cada ensamblaje es dolorosamente lento. Si incluye todos los ensamblados del sistema, podría tratarse de un bucle de iteración de 10.000. – Deane

Cuestiones relacionadas