Как вы получаете все свойства класса и его базовых классов (вверх по иерархии) с помощью Reflection? (С#)
Итак, у меня сейчас есть что-то вроде этого:
PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public);
где obj
- некоторый объект.
Проблема в том, что некоторые из свойств, которые я хочу, не находятся в obj.GetType()
, они находятся в одном из базовых классов. Если я остановлю отладчик и посмотрю на obj, мне придется прорыть несколько "базовых" записей, чтобы увидеть свойства, которые я хочу получить. Есть ли какой-либо флаг привязки, который я могу установить, чтобы он возвращал те или мне приходится рекурсивно выкапывать иерархию Type.BaseType
и делать GetProperties
для всех из них?
Ответы
Ответ 1
Используйте это:
PropertyInfo[] info = obj.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);
EDIT: Конечно, правильный ответ: Jay. GetProperties()
без параметров эквивалентен GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static )
. BindingFlags.FlattenHierarchy
здесь не играет никакой роли.
Ответ 2
Я не думаю, что это сложно.
Если вы удалите параметр 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
Ответ 3
При доступе к Type.BaseType
вы можете получить базовый тип. Вы можете рекурсивно обращаться к каждому базовому типу, и вы узнаете, когда вы достигли дна, когда ваш тип System.Object
.
Type type = obj.GetType();
PropertyInfo[] info = type.GetProperties(BindingFlags.Public);
PropertyInfo[] baseProps = type.BaseType.GetProperties(BindingFlags.Public);
Ответ 4
Я хотел бы согласиться с Николасом; если вы не знаете, что вам нужно отражение, тогда ComponentModel
является жизнеспособной альтернативой, с тем преимуществом, что вы получите правильные метаданные даже для моделей времени исполнения (например, DataView
/DataRowView
).
Например:
foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(obj))
{
Console.WriteLine("{0}={1}", prop.Name, prop.GetValue(obj));
}
Как и в стороне, вы также можете сделать несколько простых трюков производительности; вы можете сделать то же самое с отражением и Delegate.CreateDelegate
, но нет централизованного места для скрытия логики, в отличие от TypeDescriptor
с TypeDescriptionProvider
(не беспокойтесь, если они незнакомы, вы можете просто использовать код "как и"; -p).
Ответ 5
Использование:
TypeDescriptor.GetProperties(obj);