2013-04-10 13 views
16

Ich verwende Reflection, um eine Treeview mit der Klassenstruktur eines Projekts zu laden. Jedem Mitglied einer Klasse ist ein benutzerdefiniertes Attribut zugewiesen.Abrufen des Typs einer MemberInfo mit Reflektion

Ich habe kein Problem beim Abrufen der Attribute für eine Klasse mit MemberInfo.GetCustomAttributes() aber ich brauche eine Möglichkeit zu erarbeiten, wenn ein Klassenmitglied eine benutzerdefinierte Klasse ist und dann selbst analysiert, um die benutzerdefinierten Attribute zurückzugeben.

Bisher ist mein Code:

MemberInfo[] membersInfo = typeof(Project).GetProperties(); 

foreach (MemberInfo memberInfo in membersInfo) 
{ 
    foreach (object attribute in memberInfo.GetCustomAttributes(true)) 
    { 
     // Get the custom attribute of the class and store on the treeview 
     if (attribute is ReportAttribute) 
     { 
      if (((ReportAttribute)attribute).FriendlyName.Length > 0) 
      { 
       treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName }); 
      } 
     } 
     // PROBLEM HERE : I need to work out if the object is a specific type 
     //    and then use reflection to get the structure and attributes. 
    } 
} 

Gibt es eine einfache Möglichkeit, den Zieltyp einer Member Instanz so von immer ich es angemessen umgehen kann? Ich glaube, ich vermisse etwas Offensichtliches, aber ich laufe im Augenblick im Kreis herum.

Antwort

8

GetProperties gibt ein Array von PropertyInfo zurück, also sollten Sie das verwenden.
Dann ist es einfach eine Frage der Verwendung der PropertyType Eigenschaft.

PropertyInfo[] propertyInfos = typeof(Project).GetProperties(); 

foreach (PropertyInfo propertyInfo in propertyInfos) 
{ 
    // ... 
    if(propertyInfo.PropertyType == typeof(MyCustomClass)) 
     // ... 
} 
+4

Ja, die 'MemberInfo [] membersInfo =' ist ein schlechtes Zeichen. Einer der Gründe, warum ich 'var' mag - weniger Dinge, um falsch zu liegen. –

+1

Fantastisch, danke Daniel. – GrandMasterFlush

37

Ich denke, Ihnen eine bessere Leistung zu erhalten, wenn Sie um diese Erweiterung Methode tragen:

public static Type GetUnderlyingType(this MemberInfo member) 
{ 
    switch (member.MemberType) 
    { 
     case MemberTypes.Event: 
      return ((EventInfo)member).EventHandlerType; 
     case MemberTypes.Field: 
      return ((FieldInfo)member).FieldType; 
     case MemberTypes.Method: 
      return ((MethodInfo)member).ReturnType; 
     case MemberTypes.Property: 
      return ((PropertyInfo)member).PropertyType; 
     default: 
      throw new ArgumentException 
      (
      "Input MemberInfo must be if type EventInfo, FieldInfo, MethodInfo, or PropertyInfo" 
      ); 
    } 
} 

für jede MemberInfo funktionieren sollte, nicht nur PropertyInfo. Sie können MethodInfo aus dieser Liste vermeiden, da es nicht unter dem Typ selbst liegt (aber Rückgabetyp).

In Ihrem Fall:

foreach (MemberInfo memberInfo in membersInfo) 
{ 
    foreach (object attribute in memberInfo.GetCustomAttributes(true)) 
    { 
     if (attribute is ReportAttribute) 
     { 
      if (((ReportAttribute)attribute).FriendlyName.Length > 0) 
      { 
       treeItem.Items.Add(new TreeViewItem() { Header = ((ReportAttribute)attribute).FriendlyName }); 
      } 
     } 

     //if memberInfo.GetUnderlyingType() == specificType ? proceed... 
    } 
} 

Ich frage mich, warum dieser Teil der BCL hat standardmäßig nicht gewesen.

+1

Ich mag das! Fühlte sich immer ein bisschen fischig Casting, auch wenn ich wusste, dass es eine 'PropertyInfo' war. –

Verwandte Themen