2009-08-28 6 views
8
enthält

Ich habe ein benutzerdefiniertes Attribut mit dem Namen AAtribute erstellt, zum Beispiel eine Klasse namens B, in der eine oder mehrere Methoden das Attribut verwenden. Ist es möglich, die MethodInfo der Methode, die das Attribut (in diesem Fall BMethod1) enthält, als Attribut zu erhalten, ohne die gesamte Assembly durchzugehen und alle definierten Methoden für ihre Attribute zu betrachten? Und ist das eine analoge Art für andere AttributeTargets (Parameter/Typen/Eigenschaften/...)? Ich möchte kein Array aller Methoden, die diesen Attributtyp verwenden, sondern nur die Methode mit diesem Attirbute-Objekt. Ich möchte damit die Methode zusätzlich einschränken (Rückgabetyp, Parameter, Name, andere Attributverwendung, ...).Schneller Zugriff auf den Typ/method/..., der ein Attribut in C#

[AttributeUsage(AttributeTargets.Method)] 
public class AAtribute : Attribute { 

    //some fields and properties 

    public AAtribute() {//perhaps with some parameters 
     //some operations 
     MethodInfo mi;//acces to the MethodInfo with this Attribute 
         //as an Attribute (the question) 
     //some operations with the MethodInfo 
    } 

    //some methods 

} 

public class B { 

    //some fields, properties and constructors 

    [A] 
    public void BMethod1() { 
     //some operations 
    } 

    //other methods 

} 
+0

Gute Frage, ich würde gerne die Antwort auch wissen ... –

Antwort

2

Wenn ich deine Frage richtig verstanden, Sie erhalten mögen, innerhalb des Attributcode, das Objekt (ein Verfahren, das in diesem Fall), der das Attribut angewandt wird.
Ich bin mir ziemlich sicher, dass es keinen direkten Weg gibt, dies zu tun - das Attribut hat keine Kenntnis von dem Objekt, an das es angehängt ist, diese Zuordnung ist umgekehrt.

Das Beste, was ich kann Ihnen vorschlagen, ist eine Abhilfe wie folgt aus:

using System; 
using System.Reflection; 

namespace test { 

    [AttributeUsage(AttributeTargets.Method)] 
    public class AAttribute : Attribute { 
     public AAttribute(Type type,string method) { 
      MethodInfo mi = type.GetMethod(method); 
     } 
    } 

    public class B { 
     [A(typeof(B),"BMethod1")] 
     public void BMethod1() { 
     } 
    } 
} 

HINWEIS
Was wollen Sie durch den Zugriff auf die Method innerhalb des Attributs Konstruktor erreichen? Vielleicht gibt es eine alternative Möglichkeit, Ihr Ziel zu erreichen ...

EDIT

Als weitere mögliche Lösung, könnten Sie eine statische Methode in Ihrem Attribute zur Verfügung stellen, die die Prüfung durchführt - aber dies beinhaltet Iterieren über die MethodInfos.

using System; 
using System.Reflection; 
namespace test { 

    [AttributeUsage(AttributeTargets.Method)] 
    public class AAttribute : Attribute { 
     public static void CheckType<T>() { 
      foreach (MethodInfo mi in typeof(T).GetMethods()) { 
       AAttribute[] attributes = (AAttribute[])mi.GetCustomAttributes(typeof(AAttribute), false); 
       if (0 != attributes.Length) { 
        // do your checks here 
       } 
      } 
     } 
    } 

    public class B { 
     [A] 
     public void BMethod1() { 
     } 
     [A] 
     public int BMethod2() { 
      return 0; 
     } 
    } 

    public static class Program { 
     public static void Main() { 
      AAttribute.CheckType<B>(); 
     } 
    } 
} 
+0

Wie ich schon sagte, möchte ich additiol Constraints setzen (Rückgabetyp, Anzahl der Parameter, Arten der Parameter, Name der Methode, ...). Wenn die Methode nicht gültig ist, kann eine Exception ausgelöst werden. Aber was auch immer der Grund ist, wäre es nicht logisch, dass Sie auf das zugreifen können, wo das Attribut verknüpft ist? –

+0

Ja, aber was wollen Sie mit diesen Einschränkungen machen? Das Attribut wird nicht instanziiert, bis Sie versuchen, den Typ in jedem Fall wiederzugeben. –

0

Um herauszufinden, ob für eine Methode ein Attribut angewendet wurde, haben Sie bereits die MethodInfo.

var type = obj.GetType(); 
foreach(var method in type.GetMethods()) 
{ 
    var attributes = method.GetCustomAttributes(typeof(AAtribute)); 
    if(attributes.Length > 0) 
    { 
     //this method has AAtribute applied at least once 
    } 
}

+0

Ja, aber wie machst du es aus dem Attribut? Gibt es eine Möglichkeit zu wissen, auf welche Methode (oder Member) die aktuelle Instanz des Attributs angewendet wird? –

2

Ich denke, die Antwort ist nein. Oder zumindest nicht in einer vernünftigen Art und Weise. Die Instanz des Attributs wird nur erstellt, wenn Sie nach dem Attribut über MethodInfo suchen. Durch das Instanziieren der Klasse mit der Methode, die über das Attribut verfügt, wird das Attribut nicht instanziiert. Attribut-Instanzen werden nur erstellt, sobald Sie herumstochern, um sie durch Reflexion zu finden.