2009-05-28 5 views
7

Ich möchte Methoden mit einem bestimmten Attribut aufrufen. Also fahre ich durch alle Assemblys und alle Methoden, um die Methoden mit meinem Attribut zu finden. Funktioniert gut, aber wie rufe ich eine bestimmte Methode auf, wenn ich nur MethodInfo habe.Invoke-Methode von 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 
     } 
    } 
} 

Das Problem ist, dass ich die Instanz der Klasse nicht kenne, die diese bestimmte Methode enthält. Daher kann ich es nicht richtig aufrufen, da die Methoden nicht statisch sind. Ich möchte auch vermeiden, eine neue Instanz dieser Klasse zu erstellen, wenn möglich.

Antwort

5

statt Codierung:

Angenommen, Sie können es nicht statisch machen dann den Code Sie brauchen wie folgt.

Instanzmethoden hängen davon ab, auf welcher Instanz sie aufgerufen werden - es macht keinen Sinn, eine Instanzmethode aufzurufen, ohne sich darum zu kümmern, worum es sich handelt. (Wie Martin sagt, eine Instanzmethode, die sich nicht darum kümmert, welche Instanz sie aufgerufen wird, sollte fast immer statisch sein. Die einzige unmittelbare Ausnahme, die ich mir vorstellen kann, sind virtuelle Methoden, bei denen die Instanz implizit angibt, welche Implementierung verwendet werden soll.)

Erarbeiten, was es wirklich bedeutet in Ihrem Kontext für dort eine annotierte Instanz Methode. Warum versuchen Sie, Methoden trotzdem aufzurufen? Was ist das größere Bild? Welchen Kontext hast du? Ich habe den starken Verdacht, dass Sie eine Vorstellung von einem Kontext haben wollen - eine Sammlung von Objekten, die Sie aufrufen können.

+0

Ich möchte Methoden mit einem benutzerdefinierten Attribut markieren, damit sie von einer Befehlszeile aufgerufen werden können. Egal wo sie sind. Aber ich stimme Ihnen zu, dass es keinen Sinn macht, die gleichen Methoden in verschiedenen Fällen aufzurufen, in denen die Methode nicht statisch ist. Also ich werde das in einer Art Manager-Klasse verwenden, die eine Sammlung dieser Objekte enthält, um einen Aufruf für eine bestimmte Instanz pro Parameter aufzurufen. Ich denke, das wird tun, was ich will. Vielen Dank – apparat

11

Nicht statische Methoden sind instanzspezifisch. Daher müssen Sie die Klasse instanziieren, um die Methode aufzurufen. Wenn Sie die Möglichkeit haben, den Code zu ändern, in dem er definiert ist und die Methode nicht selbst Teil einer Instanz sein muss (sie greift nicht auf nicht statische Eigenschaften oder Methoden in der Klasse zu oder ändert sie nicht), dann wäre dies die beste Vorgehensweise sei, die Methode trotzdem statisch zu machen. Das erscheint mir als ein Problem im Hinblick auf die Definition des Problems

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

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

tatsächlich; Nicht-statische Methoden sind ** Instanzen ** spezifisch. statische Methoden sind klassenspezifisch. – Kris

+0

Whoops. Bearbeitet - danke. –

0

Eigentlich denke ich, was Sie tun müssen, ist eine Liste der vorhandenen Objekte zu erstellen und dann die Liste durchsuchen. Wenn Sie diese aufrufbaren Objekte erstellen, würden Sie sie in der Liste speichern (oder die Liste sollte eine Liste von Objekten anderer Art sein, die auch eine Beschreibung des aufrufbaren Objekts enthält). Dann können Sie die Liste zur Laufzeit scannen, diejenige finden, die mit dem Typ des Ereignisses übereinstimmt, das Sie bearbeiten, und dann ihre methodInfo nachschlagen und .Invoke für die Methodeninfo aufrufen, vorausgesetzt, dass das ist, was Sie tun möchten. Sie müssten auch die entsprechenden Argumente übergeben, aber Sie können dies tun, indem Sie einen Vektor von Objekten der richtigen Typen erstellen.