2009-04-10 72 views

Trả lời

595

Phản ánh; cho một ví dụ:

obj.GetType().GetProperties(); 

cho một loại:

typeof(Foo).GetProperties(); 

ví dụ:

class Foo { 
    public int A {get;set;} 
    public string B {get;set;} 
} 
... 
Foo foo = new Foo {A = 1, B = "abc"}; 
foreach(var prop in foo.GetType().GetProperties()) { 
    Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(foo, null)); 
} 

Sau phản hồi ...

  • Để có được val ue thuộc tính tĩnh, vượt qua null làm đối số đầu tiên cho GetValue
  • Để xem các thuộc tính không công khai, hãy sử dụng (ví dụ) GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance) (trả về tất cả các thuộc tính cá nhân công khai/riêng tư).
+8

Để hoàn chỉnh, đó cũng là ComponentModel, tiếp xúc bởi TypeDescriptor.GetProperties (...) - cho phép tính thời gian chạy động (phản ánh được cố định ở compile- thời gian). –

+4

Đề xuất: Mở rộng câu trả lời để bao gồm thuộc tính được bảo vệ/riêng tư/tĩnh/kế thừa. – Richard

+1

Tuyên bố foreach bạn hiển thị ngay cả các tác phẩm từ bên trong lớp bạn muốn nhận các thuộc tính của :) –

6

Bạn có thể sử dụng phản chiếu.

Type typeOfMyObject = myObject.GetType(); 
PropertyInfo[] properties =typeOfMyObject.GetProperties(); 
52

Bạn có thể sử dụng Reflection để làm điều này: (từ thư viện của tôi - điều này được các tên và giá trị)

public static Dictionary<string, object> DictionaryFromType(object atype) 
    { 
     if (atype == null) return new Dictionary<string, object>(); 
     Type t = atype.GetType(); 
     PropertyInfo[] props = t.GetProperties(); 
     Dictionary<string, object> dict = new Dictionary<string, object>(); 
     foreach (PropertyInfo prp in props) 
     { 
      object value = prp.GetValue(atype, new object[]{}); 
      dict.Add(prp.Name, value); 
     } 
     return dict; 
    } 

điều này sẽ không làm việc cho các thuộc tính với một chỉ số - cho rằng (nó trở nên khó sử dụng):

public static Dictionary<string, object> DictionaryFromType(object atype, 
    Dictionary<string, object[]> indexers) 
{ 
    /* replace GetValue() call above with: */ 
    object value = prp.GetValue(atype, ((indexers.ContainsKey(prp.Name)?indexers[prp.Name]:new string[]{}); 
} 

Ngoài ra, để chỉ nhận các thuộc tính công khai: (see MSDN on BindingFlags enum)

/* replace */ 
PropertyInfo[] props = t.GetProperties(); 
/* with */ 
PropertyInfo[] props = t.GetProperties(BindingFlags.Public) 

Điều này cũng hoạt động trên các loại ẩn danh!
Để chỉ nhận được những cái tên:

public static string[] PropertiesFromType(object atype) 
    { 
     if (atype == null) return new string[] {}; 
     Type t = atype.GetType(); 
     PropertyInfo[] props = t.GetProperties(); 
     List<string> propNames = new List<string>(); 
     foreach (PropertyInfo prp in props) 
     { 
      propNames.Add(prp.Name); 
     } 
     return propNames.ToArray(); 
    } 

Và nó chỉ là về giống cho chỉ các giá trị, hoặc bạn có thể sử dụng:

GetDictionaryFromType().Keys 
// or 
GetDictionaryFromType().Values 

Nhưng đó là chậm hơn một chút, tôi sẽ tưởng tượng.

+0

... nhưng atype.GetProperty (prp.Name) sẽ trả lại prp? –

+0

Ồ - bạn nói đúng! D'oh. –

+0

Tôi đã sửa lỗi đó ngay bây giờ. –

19

Bạn có thể sử dụng không gian tên System.Reflection với Type.GetProperties() mehod:

PropertyInfo[] propertyInfos; 
propertyInfos = typeof(MyClass).GetProperties(BindingFlags.Public|BindingFlags.Static); 
2

Tôi cũng phải đối mặt với loại này yêu cầu.

Từ cuộc thảo luận này, tôi có ý tưởng khác,

Obj.GetType().GetProperties()[0].Name 

Điều này cũng được thể hiện tên thuộc tính.

Obj.GetType().GetProperties().Count(); 

số hiển thị thuộc tính này.

Cảm ơn tất cả.Đây là cuộc thảo luận tốt đẹp.

29
public List<string> GetPropertiesNameOfClass(object pObject) 
{ 
    List<string> propertyList = new List<string>(); 
    if (pObject != null) 
    { 
     foreach (var prop in pObject.GetType().GetProperties()) 
     { 
      propertyList.Add(prop.Name); 
     } 
    } 
    return propertyList; 
} 

Chức năng này là để nhận danh sách Thuộc tính lớp.

+5

Bạn có thể muốn thay đổi điều này để sử dụng 'lợi nhuận'. Nó không phải là một vấn đề lớn, nhưng đó là một cách tốt hơn để làm điều đó. –

+1

Tôi thích điều này vì đó là (gần như) câu trả lời duy nhất không bao gồm từ * phản chiếu *. –

+4

Tuy nhiên, điều này vẫn ** sử dụng ** phản ánh tuy nhiên. – GGG

5

Đó là giải pháp của tôi

public class MyObject 
{ 
    public string value1 { get; set; } 
    public string value2 { get; set; } 

    public PropertyInfo[] GetProperties() 
    { 
     try 
     { 
      return this.GetType().GetProperties(); 
     } 
     catch (Exception ex) 
     { 

      throw ex; 
     } 
    } 

    public PropertyInfo GetByParameterName(string ParameterName) 
    { 
     try 
     { 
      return this.GetType().GetProperties().FirstOrDefault(x => x.Name == ParameterName); 
     } 
     catch (Exception ex) 
     { 

      throw ex; 
     } 
    } 

    public static MyObject SetValue(MyObject obj, string parameterName,object parameterValue) 
    { 
     try 
     { 
      obj.GetType().GetProperties().FirstOrDefault(x => x.Name == parameterName).SetValue(obj, parameterValue); 
      return obj; 
     } 
     catch (Exception ex) 
     { 
      throw ex; 
     } 
    } 
} 
2

đây được cải thiện @lucasjones trả lời. Tôi đã bao gồm các cải tiến được đề cập trong phần bình luận sau câu trả lời của anh ấy. Tôi hy vọng ai đó sẽ thấy điều này hữu ích.

public static string[] GetTypePropertyNames(object classObject, BindingFlags bindingFlags) 
{ 
    if (classObject == null) 
    { 
     throw new ArgumentNullException(nameof(classObject)); 
    } 

     var type = classObject.GetType(); 
     var propertyInfos = type.GetProperties(bindingFlags); 

     return propertyInfos.Select(propertyInfo => propertyInfo.Name).ToArray(); 
} 
5

Dựa trên câu trả lời của @ MarcGravell, đây là phiên bản hoạt động trong Unity C#.

ObjectsClass foo = this; 
foreach(var prop in foo.GetType().GetProperties()) { 
    Debug.Log("{0}={1}, " + prop.Name + ", " + prop.GetValue(foo, null)); 
} 
Các vấn đề liên quan