2009-06-20 7 views
4

Ich habe eine Klasse Bar wie folgt aus:Reflektieren über die Eigenschaft, Attribute zu erhalten. Wie zu tun, wenn sie woanders definiert sind?

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; } } 
} 

Ich brauche das Attribut [Range (0255)] reflektieren NUR auf dem Grundstück Bar.FooProp zu finden. Ich meine, die Requisite ist in der Klasseninstanz (.. new Foo()) dekoriert, nicht in der Klasse, wenn ich gerade analysiere. Infact Bar.FooProp hat keine Attribute

EDIT

I Attribute auf die Schnittstelle der Definition bewegt, also was ich tun muss, ist die geerbten Schnittstellen Parsen sie zu finden. Ich kann tun, weil Bar Klasse IFoo.In diesem speziellen Fall implementieren müssen, ich habe das Glück, aber das Problem bleibt, wenn ich keine Schnittstellen ... Ich Note für das nächste Mal

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)); 
     } 
     } 
    } 
    } 

Antwort

1

nehmen Bei der Suche bei FooProp gibt es nichts, um die Existenz eines Foo (an irgendeinem Punkt) zu identifizieren. Vielleicht könnten Sie ein Attribut hinzufügen, um das Feld foo zu identifizieren und darüber nachzudenken (über FieldInfo.FieldType)?

+0

Tatsächlich spiegelt der Schlüssel "inside" die Get/Set-Methode wider. Ich weiß nicht, ob es eine Möglichkeit gibt, den Return-Parameter zu verstehen, ist ein Aufruf einer Instanz-Methode. –

+1

Wenn Sie * innerhalb * der get/set sind, dann kennen Sie den Typ ... benutzen Sie einfach den bekannten Typ ... ? –

+0

mhh ... ich dachte, die Attribute der Schnittstellendefinition zu verschieben. Also reflektiere ich direkt über die geerbten Attribute nach Interface, nicht über die implementierten Eigenschaften. Könnte es sein, Marc? –

2

Ich hatte eine ähnliche Situation vor einer Weile, wo ich ein Attribut für eine Methode in einer Schnittstelle deklariert hatte, und ich wollte das Attribut von einer Methode auf einem Typ, der die Schnittstelle implementiert. Zum Beispiel:

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

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

Der folgende Code verwendet wird, um alle der Schnittstelle vom Typ implementiert zu überprüfen, siehe die Schnittstellenelemente des gegebenen method Arbeitsgeräte (unter Verwendung von GetInterfaceMap) und gibt alle Attribute auf diesen Mitgliedern. Genau davor überprüfe ich auch, ob das Attribut in der Methode selbst vorhanden ist.

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 interesting .. –