Làm thế nào để có được danh sách các thuộc tính của một lớp?


597

Làm thế nào để tôi có được một danh sách tất cả các thuộc tính của một lớp?

Câu trả lời:


797

Suy tư; 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));
}

Theo dõi phản hồi ...

  • Để lấy giá trị của các thuộc tính tĩnh, chuyển nulllàm đối số đầu tiên choGetValue
  • Để 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ông khai / riêng).

13
Để hoàn thiện, cũng có ElementModel, được hiển thị bởi TypeDescriptor.GetProperIES (...) - cho phép các thuộc tính thời gian chạy động (phản xạ được cố định tại thời gian biên dịch).
Marc Gravell

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

1
Câu lệnh foreach mà bạn hiển thị thậm chí hoạt động từ trong lớp bạn muốn nhận các thuộc tính của :)
Halfpastfour.am

Tôi không rõ ràng về cách mà các bình luận bổ sung được nêu, nhưng sử dụng cả 3 cờ cũng mang lại cho bạn internalcác thuộc tính. Có lẽ tôi là người duy nhất bị treo lên trên cú pháp private/ non-public?
brichin

1
@Tadej bạn đang nhắm mục tiêu khung nào? nếu bạn đang sử dụng .NET core, bạn cần đảm bảo rằng bạn có lệnh using System.ReflectionSystem.Reflection.TypeExtensionsgói được tham chiếu - điều này cung cấp bề mặt API bị thiếu thông qua các phương thức mở rộng
Marc Gravell

92

Bạn có thể sử dụng Reflection để làm điều này: (từ thư viện của tôi - cái này lấy 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 hoạt động đối với các thuộc tính có chỉ mục - vì điều đó (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: ( xem MSDN trên 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!
Để có được 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ỉ giống nhau cho 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.


... nhưng atype.GetProperty (prp.Name) sẽ trả về prp?
Marc Gravell

5
Về bit thuộc tính công khai, theo bài viết MSDN được liên kết: "Lưu ý Bạn phải chỉ định Instance hoặc Tĩnh cùng với Public hoặc NonPublic hoặc không có thành viên nào được trả về.". Vì vậy, mã mẫu phải là: t.GetProperties(BindingFlags.Instance | BindingFlags.Public)hoặct.GetProperties(BindingFlags.Static | BindingFlags.Public)
Carl Sharman

không tìm kiếm mã, tôi đang tìm một lời giải thích cho sự phản ánh và wow, rất được đánh giá cao! Đặt cái chung này và bạn cũng có thể nói chương trình của bạn có siêu năng lực;)
Jaquarh 18/03/2016

37
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;
}

Hàm này dùng để lấy danh sách Thuộc tính lớp.


7
Bạn có thể muốn thay đổi điều này để sử dụng yield return. 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 đó.
Matthew Haugen

1
Tôi thích điều này bởi vì đây là (gần như) câu trả lời duy nhất không bao gồm sự phản ánh từ .

9
Nhưng điều này vẫn sử dụng sự phản ánh tuy nhiên.
GGG

2
Tôi cho rằng điều này tốt hơn nhiều pObject.GetType (). GetProperIES (). Chọn (p => p.Name)
Thất vọng

23

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

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

23

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

8

Đó 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;
        }
    }
}

6

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

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

3

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

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

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

Điều này cũng hiển thị tên tài sản.

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

Điều này cho thấy số lượng tài sản.

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


3

Đây là câu trả lời @lucasjones được cải thiện. Tôi bao gồm những 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ẽ tìm 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();
 }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.