簡體   English   中英

您如何使用反射獲得一個類及其基類(在層次結構中)的所有屬性? (C#)

[英]How do you get the all properties of a class and its base classes (up the hierarchy) with Reflection? (C#)

所以我現在擁有的是這樣的:

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

其中obj是某個對象。

問題是我想要的一些屬性不在obj.GetType()中,它們在更進一步的基類之一中。 如果我停止調試器並查看 obj,我必須挖掘一些“基礎”條目才能查看我想要獲取的屬性。 是否可以設置一些綁定標志以使其返回這些標志,或者我是否必須遞歸地挖掘Type.BaseType層次結構並對所有這些標志執行GetProperties

用這個:

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

編輯:當然,正確的答案是Jay的答案。 不帶參數的GetProperties()等效於GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static ) BindingFlags.FlattenHierarchy在這里不起作用。

我覺得沒那么復雜。

如果您將BindingFlags參數刪除到 GetProperties,我認為您會得到您正在尋找的結果:

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

生產

MyProperty2
    MyProperty

如果您訪問Type.BaseType ,您可以獲得基本類型。 您可以遞歸地訪問每種基本類型,並且當您的類型為System.Object時,您會知道何時觸底。

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

我傾向於同意 Nicolas 的觀點。 除非您知道需要反射,否則ComponentModel是一個可行的替代方案,其優點是即使對於運行時模型(例如DataView / DataRowView ),您也可以獲得正確的元數據。

例如:

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

順便說一句,您還可以用它做一些簡單的 性能技巧 你可以對反射和Delegate.CreateDelegate做同樣的事情,但是沒有集中的地方來隱藏邏輯,這與帶有TypeDescriptorTypeDescriptionProvider不同(如果這些不熟悉,請不要擔心;你可以“按原樣”使用代碼; -p)。

利用:

TypeDescriptor.GetProperties(obj);

為了完整起見,您不能以這種方式從基類中獲取 PRIVATE 字段和屬性。 您必須為此使用遞歸循環:

public static IEnumerable<PropertyInfo> GetProperties(Type type, bool forGetter)
{
    // Loop over public and protected members
    foreach (var item in type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
    {
        yield return item;
    }

    // Get first base type
    type = type.BaseType;

    // Find their "private" memebers
    while (type != null && type != typeof(object))
    {
        // Loop over non-public members
        foreach (var item in type.GetProperties(BindingFlags.Instance | BindingFlags.NonPublic))
        {
            // Make sure it's private!
            // To prevent doubleing up on protected members
            var methodInfo = forGetter ? item.GetGetMethod(true) : item.GetSetMethod(true);
            if (methodInfo != null && methodInfo.IsPrivate)
            {
                yield return item;
            }
        }

        // Get next base type.
        type = type.BaseType;
    }
}

public static IEnumerable<FieldInfo> GetFields(Type type)
{
    // Loop over public and protected members
    foreach (var item in type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic))
    {
        yield return item;
    }

    // Get first base type
    type = type.BaseType;

    // Find their "private" memebers
    while (type != null && type != typeof(object))
    {
        // Loop over non-public members
        foreach (var item in type.GetFields(BindingFlags.Instance | BindingFlags.NonPublic))
        {
            // Make sure it's private!
            // To prevent doubleing up on protected members
            if (item.IsPrivate)
            {
                yield return item;
            }
        }

        // Get next base type.
        type = type.BaseType;
    }
}

注意:您將獲得兩次受保護的字段和屬性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM