2013-04-10 31 views
16

Tôi đang sử dụng phản chiếu để tải một ảnh tre có cấu trúc lớp của một dự án. Mỗi thành viên trong một lớp có một thuộc tính tùy chỉnh được gán cho chúng.Nhận loại hình MemberInfo với sự phản ánh

Tôi không có một vấn đề nhận được các thuộc tính cho một lớp học sử dụng MemberInfo.GetCustomAttributes() tuy nhiên tôi cần một cách để làm việc ra nếu một thành viên lớp là một lớp tùy chỉnh và sau đó cần phân tích cú pháp riêng của mình để trả lại thuộc tính tùy chỉnh.

Cho đến nay, mã của tôi là:

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

Có một cách dễ dàng để nhận được các loại mục tiêu của một trường hợp MemberInfo vì vậy tôi có thể xử lý nó một cách thích hợp? Tôi cảm thấy tôi đang thiếu một cái gì đó hiển nhiên nhưng tôi đang đi vòng trong vòng tròn ở phút.

Trả lời

8

GetProperties trả về một mảng PropertyInfo để bạn nên sử dụng.
Sau đó, chỉ đơn giản là sử dụng thuộc tính PropertyType.

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

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

vâng, thành viên 'MemberInfo []Info =' là dấu hiệu xấu. Một trong những lý do tôi thích 'var' - ít điều hơn để hiểu sai. –

+1

Tuyệt vời, cảm ơn Daniel. – GrandMasterFlush

37

Tôi nghĩ bạn có thể có được hiệu suất tốt hơn nếu bạn mang theo phương pháp mở rộng này:

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

nên làm việc cho bất kỳ MemberInfo, không chỉ PropertyInfo. Bạn có thể tránh MethodInfo từ danh sách đó vì nó không nằm dưới loại nằm trên mỗi loại (nhưng kiểu trả về).

Trong trường hợp của bạn:

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

Tôi tự hỏi tại sao điều này vẫn chưa được một phần của BCL theo mặc định.

+1

Tôi thích điều này! Luôn luôn cảm thấy một chút đúc cá, ngay cả khi tôi biết nó là một 'PropertyInfo'. –

Các vấn đề liên quan