Accès rapide au type / méthode / ... qui détient un attribut en C #
-
20-09-2019 - |
Question
J'ai fait un attribut personnalisé nommé 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 (l'un des) ses attributs sans marcher à travers toute l'assemblée et regardant toutes les méthodes définies pour leurs attributs? Et est leur façon analogique pour d'autres AttributeTargets (Paramètres / Types / Propriétés / ...)? I'don't veulent un tableau de toutes les méthodes qui utilisent ce type d'attribut, mais juste la méthode avec ce Attirbute-objet dans particual. Je veux l'utiliser pour mettre des contraintes supplémentaires sur la méthode (type de retour, paramètre, nom, autre attribut-utilisation, ...).
[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
}
La solution
Si je comprends bien votre question, vous voulez obtenir, dans le code d'attribut , l'objet (une méthode dans ce cas) auquel l'attribut est appliqué.
Je suis sûr qu'il n'y a pas moyen direct de faire - l'attribut n'a pas connaissance de l'objet auquel il est attaché, cette association est l'inverse.
Le mieux que je peux vous suggérer une solution de contournement est comme 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
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>();
}
}
}
Autres conseils
Je pense que la réponse est non. Ou du moins pas de façon raisonnable. L'instance de l'attribut est construit uniquement une fois que vous recherchez l'attribut à travers le MethodInfo. Instanciation de la classe qui a la méthode qui a l'attribut ne sera pas instancier l'attribut. Les instances d'attributs ne sont créés une fois que vous commencez à fouiller pour les trouver par la réflexion.
Pour savoir si une méthode a un attribut appliqué, vous avez déjà la 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
}
}