2009-08-28 9 views
8

He creado un atributo personalizado aquí denominado AAtribute, y por ejemplo una clase llamada B donde uno o más métodos usan el atributo. ¿Es posible obtener el MethodInfo del método que mantiene el atributo (en este caso BMethod1) como (uno de) sus atributos sin recorrer todo el conjunto y observar todos los métodos definidos para sus atributos? ¿Y es su forma análoga para otros AttributeTargets (Parameters/Types/Properties/...)? No quiero una matriz de todos los métodos que usan ese tipo de atributo, pero solo el método con este objeto Attirbute en particular. Quiero usarlo para poner restricciones adicionales en el método (Tipo de devolución, parámetro, nombre, otro uso de atributos, ...).Acceso rápido al tipo/método/... que contiene un atributo 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

Buena pregunta, me gustaría saber la respuesta también ... –

Respuesta

2

Si he entendido bien su pregunta, usted quiere conseguir, dentro del código atributo, el objeto (un método en este caso) al que se aplica el atributo.
Estoy bastante seguro de que no hay una forma directa de hacerlo: el atributo no tiene conocimiento del objeto al que está conectado, esta asociación es al revés.

Lo mejor que puedo sugerir que es una solución similar a la siguiente:

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

NOTA
¿Qué quiere lograr mediante el acceso al interior de MethodInfo constructor del atributo? Tal vez hay una forma alternativa de obtener su objetivo ...

EDITAR

Como otra posible solución, es posible proporcionar un método estático en su atributo que realiza el chequeo - pero esto implica iterar sobre los 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

Como ya he dicho, quiero ponerle restricciones adicionales (tipo de retorno, cantidad de parámetros, tipos de parámetros, nombre del método, ...). Si el método no es válido, se puede lanzar una excepción. Pero sea cual sea el motivo, ¿no sería lógico que pueda acceder al elemento al que está vinculado el atributo? –

+0

Sí, pero ¿qué quieres hacer con esas limitaciones? El atributo no se instanciará hasta que intente reflejar el tipo, en cualquier caso. –

0

Para saber si un método tiene un atributo aplicado, ya tiene el 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

Sí, pero ¿cómo se hace desde el interior del atributo? ¿Hay alguna forma de saber a qué método (o miembro) se aplica la instancia actual del atributo? –

2

Creo que la respuesta es no. O al menos no de una manera razonable. La instancia del atributo solo se crea una vez que busca el atributo a través de MethodInfo. La instanciación de la clase que tiene el método que tiene el atributo no instanciará el atributo. Las instancias de atributo solo se crean una vez que comienzas a buscarlas a través de la reflexión.

Cuestiones relacionadas