2008-10-28 7 views
22

Vì vậy, những gì tôi có ngay bây giờ là một cái gì đó như thế này:Làm thế nào để bạn có được tất cả các thuộc tính của một lớp và các lớp cơ sở của nó (lên cấu trúc phân cấp) với Reflection? (C#)

PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public); 

nơi obj là một số đối tượng.

Vấn đề là một số thuộc tính tôi muốn không nằm trong số obj.GetType() chúng thuộc một trong các lớp cơ sở tiếp tục. Nếu tôi dừng trình gỡ rối và nhìn vào obj, tôi phải đào qua một vài mục "cơ sở" để xem các thuộc tính mà tôi muốn nhận được. Có một số lá cờ ràng buộc tôi có thể thiết lập để có nó trở lại những người hoặc làm tôi phải đệ quy đào qua hệ thống phân cấp Type.BaseType và làm GetProperties trên tất cả chúng?

Trả lời

21

Sử dụng này:

PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); 

EDIT: Tất nhiên câu trả lời đúng là của Jay. GetProperties() không có tham số tương đương với GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static). BindingFlags.FlattenHierarchy không có vai trò nào ở đây.

+0

Tôi đánh dấu đây là câu trả lời vì mặc dù công việc của Jay và sẽ đưa tôi những gì tôi muốn, điều này giải thích tại sao nó hoạt động. Tôi chỉ giả định rằng nếu cả Instance lẫn Static đều không được chỉ định, nó sẽ mặc định cả hai, trong khi thực tế nó không trả về. – Davy8

+0

Không có thuộc tính cấp cao nhất trong đối tượng tôi đang xem, vì vậy tôi cho rằng nó chỉ là cố gắng lấy lại những cấp cao nhất khi nó không trả về gì, trong khi thực tế nó không trả về gì bởi vì nó đang cố lấy các thuộc tính không Tĩnh cũng không thể. – Davy8

4

Nếu bạn truy cập Type.BaseType, bạn có thể nhận loại cơ sở. Bạn có thể truy cập đệ quy từng loại cơ sở và bạn sẽ biết khi nào bạn đã chạm đáy khi loại của bạn là System.Object.

Type type = obj.GetType(); 
PropertyInfo[] info = type.GetProperties(BindingFlags.Public); 
PropertyInfo[] baseProps = type.BaseType.GetProperties(BindingFlags.Public); 
+2

yêu bạn. Tốt nhất. Tại sao mọi người đã bỏ phiếu xuống cái này? – argatxa

+0

Tuyệt! Cám ơn vì cái này. Đã lưu ngày cho thành viên tĩnh trong lớp cơ sở. – Justjyde

12

Tôi không nghĩ nó quá phức tạp.

Nếu bạn loại bỏ các tham số để BindingFlags GetProperties, tôi nghĩ rằng bạn sẽ có được kết quả mà bạn đang tìm kiếm:

class B 
    { 
     public int MyProperty { get; set; } 
    } 

    class C : B 
    { 
     public string MyProperty2 { get; set; } 
    } 

    static void Main(string[] args) 
    { 
     PropertyInfo[] info = new C().GetType().GetProperties(); 
     foreach (var pi in info) 
     { 
      Console.WriteLine(pi.Name); 
     } 
    } 

sản xuất

 
    MyProperty2 
    MyProperty 
2

Sử dụng:

TypeDescriptor.GetProperties(obj); 
3

tôi sẽ có xu hướng đồng ý với Nicolas; trừ khi bạn biết bạn cần phản ánh, thì ComponentModel là một giải pháp khả thi, với lợi thế là bạn sẽ nhận được siêu dữ liệu chính xác ngay cả đối với các mô hình thời gian chạy (chẳng hạn như DataView/DataRowView).

Ví dụ:

foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj)) 
    { 
     Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj)); 
    } 

Là một sang một bên, bạn cũng có thể làm một số đơn giản performance tricks với điều này; bạn có thể làm tương tự với sự phản chiếu và Delegate.CreateDelegate, nhưng không có nơi tập trung để ẩn logic đi, không giống như TypeDescriptor với một số TypeDescriptionProvider (đừng lo lắng nếu chúng không quen thuộc; bạn chỉ có thể sử dụng mã "như là" ;-p).