2013-04-10 10 views
16

Używam refleksji do załadowania widoku drzewa ze strukturą klas projektu. Każdy członek w klasie ma przypisany atrybut niestandardowy.Uzyskiwanie typu MemberInfo z odbiciem

Nie mam problemu z uzyskaniem atrybutów dla klasy przy użyciu MemberInfo.GetCustomAttributes(), ale potrzebuję sposobu pracy, jeśli członek klasy jest niestandardową klasą, a następnie potrzebuje parsowania się, aby zwrócić niestandardowe atrybuty.

tej pory mój kod to:

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

Czy istnieje prosty sposób na uzyskanie typ docelowy instancji MemberInfo więc mogę poradzić odpowiednio? Czuję, że brakuje mi czegoś oczywistego, ale z każdą chwilą kręcę się w kółko.

Odpowiedz

8

GetProperties zwraca tablicę z PropertyInfo, więc powinieneś jej użyć.
To jest po prostu kwestia użycia właściwości PropertyType.

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

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

tak, 'MemberInfo [] membersInfo =' jest złym znakiem. Jednym z powodów, dla których lubię "var" - mniej rzeczy, aby się nie pomylić. –

+1

Fantastyczne, dzięki Daniel. – GrandMasterFlush

37

Myślę, że można uzyskać lepsze wyniki, jeśli nosisz tej metody wydłużania:

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

powinny pracować dla każdej MemberInfo, nie tylko PropertyInfo. Możesz ominąć MethodInfo z tej listy, ponieważ nie jest to typ leżący jako taki (ale typ zwrotu).

W twoim przypadku:

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

Zastanawiam się, dlaczego nie było to częścią BCL domyślnie.

+1

Podoba mi się to! Zawsze czułem się trochę podejrzanie, nawet gdy wiedziałem, że to "PropertyInfo". –