Как вы получаете все свойства класса и его базовых классов (вверх по иерархии) с помощью Reflection? (С #) - PullRequest
25 голосов
/ 29 октября 2008

Итак, у меня сейчас что-то вроде этого:

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

, где obj - некоторый объект.

Проблема в том, что некоторые свойства, которые мне нужны, отсутствуют в obj.GetType(), они находятся в одном из базовых классов далее. Если я остановлю отладчик и посмотрю на obj, мне придется пролистать несколько «базовых» записей, чтобы увидеть свойства, к которым я хочу получить. Есть ли какой-нибудь флаг привязки, который я могу установить, чтобы он возвращал их, или мне нужно рекурсивно копаться в иерархии Type.BaseType и делать GetProperties для всех из них?

Ответы [ 5 ]

24 голосов
/ 29 октября 2008

Используйте это:

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

РЕДАКТИРОВАТЬ: Конечно, правильный ответ это Jay . GetProperties() без параметров эквивалентно GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static ). BindingFlags.FlattenHierarchy здесь не играет роли.

14 голосов
/ 29 октября 2008

Не думаю, что это так сложно.

Если вы удалите параметр 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
5 голосов
/ 29 октября 2008

Если вы получаете доступ к Type.BaseType, вы можете получить базовый тип. Вы можете получить рекурсивный доступ к каждому базовому типу, и вы узнаете, когда достигли дна, когда ваш тип System.Object.

Type type = obj.GetType();
PropertyInfo[] info = type.GetProperties(BindingFlags.Public);
PropertyInfo[] baseProps = type.BaseType.GetProperties(BindingFlags.Public);
3 голосов
/ 29 октября 2008

Я склонен согласиться с Николасом; если вы не знаете, что вам нужно размышление, то ComponentModel является жизнеспособной альтернативой, с тем преимуществом, что вы получите правильные метаданные даже для моделей времени выполнения (например, DataView / DataRowView).

Например:

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

Кроме того, вы также можете сделать несколько простых трюков производительности с этим; вы можете сделать то же самое с отражением и Delegate.CreateDelegate, но нет централизованного места, чтобы скрыть логику, в отличие от TypeDescriptor с TypeDescriptionProvider (не волнуйтесь, если они незнакомы; вы можете просто использовать код " как есть ";-p).

2 голосов
/ 29 октября 2008

Использование:

TypeDescriptor.GetProperties(obj);
...