2009-08-28 4 views
8

J'ai créé un attribut personnalisé appelé ici AAtribute, et par exemple une classe appelée B où une ou plusieurs méthodes utilisent l'attribut. Est-il possible d'obtenir le MethodInfo de la méthode qui détient l'attribut (dans ce cas BMethod1) comme (un de) ses attributs sans marcher à travers l'ensemble de l'ensemble et en regardant toutes les méthodes définies pour leurs attributs? Et est-ce une manière analogique pour d'autres AttributeTargets (Paramètres/Types/Propriétés/...)? Je ne veux pas un tableau de toutes les méthodes qui utilisent ce type d'attribut, mais juste la méthode avec cet objet Attirbute en particulier. Je veux l'utiliser pour mettre des contraintes supplémentaires sur la méthode (type de retour, paramètre, nom, autre utilisation de l'attribut, ...).Accès rapide au type/méthode/... qui contient un attribut en 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

Bonne question, j'aimerais connaître la réponse aussi ... –

Répondre

2

Si je comprends bien votre question, vous voulez obtenir, à l'intérieur du code d'attribut, l'objet (une méthode dans ce cas) auquel l'attribut est appliqué.
Je suis assez sûr qu'il n'y a pas de moyen direct de le faire - l'attribut n'a aucune connaissance de l'objet auquel il est attaché, cette association est l'inverse.

Le meilleur que je peux vous suggérer une solution de contournement est comme ce qui suit:

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() { 
     } 
    } 
} 

NOTE
Que voulez-vous atteindre en accédant à la MethodInfo à l'intérieur du constructeur de l'attribut? Peut-être il y a une autre façon d'obtenir votre objectif ...

EDIT

Comme une autre solution possible, vous pouvez fournir une méthode statique dans votre attribut qui fait la vérification - mais cela implique itérer sur les 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

Comme je l'ai déjà dit, je veux y ajouter des contraintes additiol (type de retour, nombre de paramètres, types de paramètres, nom de la méthode, ...). Si la méthode n'est pas valide, une exception peut être générée. Mais quelle que soit la raison, n'est-ce pas logique que vous puissiez accéder à la chose à laquelle l'attribut est lié? –

+0

Oui, mais que voulez-vous faire avec ces contraintes? L'attribut ne sera pas instancié jusqu'à ce que vous essayez de refléter le type, dans tous les cas. –

0

Pour savoir si une méthode est associée à un attribut, vous avez déjà le 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

Ouais, mais comment le faites-vous depuis l'intérieur de l'attribut? Existe-t-il un moyen de savoir à quelle méthode (ou membre) l'instance actuelle de l'attribut est-elle appliquée? –

2

Je pense que la réponse est non. Ou du moins pas de manière raisonnable. L'instance de l'attribut est construite uniquement lorsque vous recherchez l'attribut via MethodInfo. L'instanciation de la classe qui a la méthode qui a l'attribut n'instanciera pas l'attribut. Les instances d'attribut ne sont créées qu'une fois que vous avez commencé à fouiller pour les trouver par réflexion.