2009-05-28 18 views
7

Deseo invocar métodos con un determinado atributo. Así que voy recorriendo todos los ensamblados y todos los métodos para encontrar los métodos con mi atributo. Funciona bien, pero ¿cómo invoco un determinado método cuando solo tengo MethodInfo?Método de invocación por MethodInfo

AppDomain app = AppDomain.CurrentDomain; 
Assembly[] ass = app.GetAssemblies(); 
Type[] types; 
foreach (Assembly a in ass) 
{ 
    types = a.GetTypes(); 
    foreach (Type t in types) 
    { 
     MethodInfo[] methods = t.GetMethods(); 
     foreach (MethodInfo method in methods) 
     { 
      // Invoke a certain method 
     } 
    } 
} 

El problema es que no conozco la instancia de la clase que contiene ese método. Entonces no puedo invocarlo correctamente porque los métodos no son estáticos. También quiero evitar crear una nueva instancia de esta clase si es posible.

Respuesta

5

Esto me parece un problema en cuanto a la definición del problema en lugar de la codificación.

Los métodos de instancia dependen de la instancia a la que se llamen; no tiene sentido llamar a un método de instancia sin preocuparse por cómo se llama. (Como dice Martin, un método de instancia que no le importa a qué instancia se lo llama debe ser casi siempre estático. La única excepción inmediata que puedo pensar para esto son los métodos virtuales, donde la instancia especifica implícitamente qué implementación usar).

Resuelva lo que realmente significa en su contexto para que exista un método de instancia anotado. ¿Por qué intentas invocar métodos de todos modos? ¿Cuál es la imagen más grande? ¿Qué contexto tienes? Sospecho fuertemente que querrá una noción de contexto: una colección de objetos que puede llamar a los métodos de instancia.

+0

Lo que quiero hacer es marcar métodos con un atributo personalizado para permitir que sean invocados por una línea de comandos. No importa donde estén. Pero estoy de acuerdo con usted en que no tiene sentido invocar los mismos métodos en varias instancias donde el método no es estático. Así que lo usaré en una especie de clase de administrador que contiene una colección de estos objetos para invocar una invocación en una instancia específica por cada parámetro. Creo que esto hará lo que yo quiera. Gracias – apparat

11

Los métodos no estáticos son específicos de instancia, por lo que debe crear una instancia de la clase para invocar el método. Si tiene la capacidad de cambiar el código donde está definido y el método no requiere ser parte de una instancia (no accede ni modifica ninguna propiedad o método no estático dentro de la clase), la mejor práctica sería: ser para hacer el método estático de todos modos.

Suponiendo que no se puede hacer que sea estática entonces el código que necesita es la siguiente:

foreach (Type t in types) 
    { 
      object instance = Activator.CreateInstance(t); 

      MethodInfo[] methods = t.GetMethods(); 
      foreach (MethodInfo method in methods) 
      {      
       method.Invoke(instance, params...);  
      } 
    } 
+0

en realidad; Los métodos no estáticos son ** instancia ** específicos. los métodos estáticos son específicos de clase. – Kris

+0

Whoops. Editado, gracias. –

0

En realidad, creo que lo que debe hacer es crear una lista de los objetos existentes y luego buscar en la lista. Entonces, al crear estos objetos invocables, los almacenaría en la lista (o tal vez la lista debería ser una lista de objetos de otro tipo que también tenga una descripción del objeto invocable). Luego puede escanear la lista en tiempo de ejecución, encontrar la que coincida con el tipo de evento que está manejando, y luego buscar su methodInfo y llamar a .Invocar la información del método, suponiendo que eso es lo que quiere hacer. También necesitaría pasar los argumentos apropiados, pero puede hacerlo creando un vector de objetos de los tipos correctos.

Cuestiones relacionadas