2009-06-20 7 views
4

une barre de classe comme ceci:Réflexion sur la propriété pour obtenir des attributs. Comment faire quand ils sont définis ailleurs? Je

class Foo : IFoo { 
    [Range(0,255)] 
    public int? FooProp {get; set} 
} 

class Bar : IFoo 
{ 
    private Foo foo = new Foo(); 
    public int? FooProp { get { return foo.FooProp; } 
         set { foo.FooProp= value; } } 
} 

Je dois trouver l'attribut [Range (0255)] qui reflète uniquement sur la propriété Bar.FooProp. Je veux dire, le prop est décoré dans l'instance de classe (.. new Foo()) pas dans la classe quand je suis en train d'analyser. Enfait Bar.FooProp n'a pas d'attributs

EDIT

Je déplaçais attributs sur la définition de l'interface, donc ce que je dois faire est l'analyse des interfaces héritées pour les trouver. Je peux le faire parce que la classe Bar doit mettre en œuvre que je suis chanceux IFoo.In ce cas particulier, mais le problème reste quand j'ai aucune interface ... Je prends note pour la prochaine fois

foreach(PropertyInfo property in properties) 
{ 
    IList<Type> interfaces = property.ReflectedType.GetInterfaces(); 
    IList<CustomAttributeData> attrList; 
    foreach(Type anInterface in interfaces) 
    { 
    IList<PropertyInfo> props = anInterface.GetProperties(); 
    foreach(PropertyInfo prop in props) 
    { 
     if(prop.Name.Equals(property.Name)) 
     { 
     attrList = CustomAttributeData.GetCustomAttributes(prop); 
     attributes = new StringBuilder(); 
     foreach(CustomAttributeData attrData in attrList) 
     { 
      attributes.AppendFormat(ATTR_FORMAT, 
             GetCustomAttributeFromType(prop)); 
     } 
     } 
    } 
    } 

Répondre

1

Lorsque vous cherchez à FooProp, il n'y a rien pour identifier l'existence d'un Foo (à tout moment). Peut-être pourriez-vous ajouter un attribut pour identifier le champ foo et y réfléchir (via FieldInfo.FieldType)?

+0

En fait, la clé reflète "inside" la méthode get/set. Je ne sais pas s'il y a un moyen de comprendre le retour param est un appel à une méthode d'instance .. –

+1

Si vous êtes * dans * le get/set, alors vous connaissez déjà le type ... il suffit d'utiliser le type connu ... ? –

+0

mhh ... Je pensais à déplacer les attributs de la définition de l'interface. Donc je réfléchis directement sur les attribs hérités par l'interface, pas sur les propriétés implémentées. Peut-être raison, Marc? –

2

J'ai eu une situation similaire il y a quelque temps où j'avais un attribut déclaré sur une méthode dans une interface, et je voulais obtenir l'attribut d'une méthode sur un type implémentant l'interface. Par exemple:

interface I { 
    [MyAttribute] 
    void Method(); 
} 

class C : I { 
    void Method() { } 
} 

Le code ci-dessous permet de vérifier l'ensemble de l'interface implémentée par le type, voir quels éléments d'interface les données method implémente (en utilisant GetInterfaceMap) et renvoie tous les attributs sur les membres. Juste avant cela, je vérifie également si l'attribut est présent sur la méthode elle-même.

IEnumerable<MyAttribute> interfaceAttributes = 
    from i in method.DeclaringType.GetInterfaces() 
    let map = method.DeclaringType.GetInterfaceMap(i) 
    let index = GetMethodIndex(map.TargetMethods, method) 
    where index >= 0 
    let interfaceMethod = map.InterfaceMethods[index] 
    from attribute in interfaceMethod.GetCustomAttributes<MyAttribute>(true) 
    select attribute; 

... 

static int GetMethodIndex(MethodInfo[] targetMethods, MethodInfo method) { 
    return targetMethods.IndexOf(target => 
     target.Name == method.Name 
     && target.DeclaringType == method.DeclaringType 
     && target.ReturnType == method.ReturnType 
     && target.GetParameters().SequenceEqual(method.GetParameters(), PIC) 
); 
} 
+0

mhhh intéressant .. –