ТипDescriptor.GetProperties() vs Type.GetProperties()
Рассмотрим следующий код.
Object obj;
PropertyDescriptorCollection A = TypeDescriptor.GetProperties(obj);
PropertyInfo[] B = obj.GetType().GetProperties(); // EDIT*
Я пытаюсь понять разницу между A и B. Из того, что я понимаю TypeDescriptor.GetProperties(), возвратит пользовательские свойства TypeDescriptor, где в качестве Type.GetProperties() будет возвращать только внутренние "реальные" свойства объекта. Это правильно? Если obj не имеет каких-либо пользовательских свойств TypeDescriptor, тогда он по умолчанию также возвращает литеральные внутренние свойства объекта.
* Оригинальная вторая строка кода до EDIT (имела неправильное возвращаемое значение):
PropertyDescriptorCollection B = obj.GetType(). GetProperties();
Ответы
Ответ 1
obj.GetType().GetProperties()
не возвращает PropertyDescriptorCollection
, он возвращает System.Reflection.PropertyInfo[]
. Класс PropertyInfo
делает, как вы полагаете, только фактические свойства, созданные на объекте. A PropertyDescriptor
является либо конкретным конкретным потомком класса PropertyDescriptor
(реализуемым типом, определяющим пользовательский дескриптор), либо является экземпляром закрытого внутреннего класса ReflectPropertyDescriptor
, который использует класс PropertyInfo
для обеспечения динамического вызова свойства.
Итак, для класса, который не определяет пользовательский дескриптор, вы будете функционально возвращать те же объекты, хотя PropertyDescriptor
абстрагируется от PropertyInfo
.
Ответ 2
Класс TypeDescriptor
используется в дизайнерах, чтобы они могли взаимодействовать с средой разработки. В частности, дизайнеры могут переопределять и расширять различные функции TypeDescriptor
, но не Type
.
Один хороший пример - работа с элементами управления, привязанными к данным. Свойство DataSource
имеет тип System.Object
, но во время разработки это свойство заменяется новым свойством, имеющим более богатый пользовательский интерфейс времени разработки.
Ответ 3
Класс TypeDescriptor
возвращает PropertyDescriptor
объекты, которые представляют свойства в типе obj
, а также любые другие свойства, которые были внесены в этот объект или его тип.
Компонентная модель на самом деле довольно сложна, но, как вы описали, базовая реализация TypeDescriptor.GetProperties()
вернет ReflectPropertyDescriptor
экземпляры, которые представляют косвенность к типичным объектам PropertyInfo
. Вы можете использовать объекты PropertyDescriptor
, очень похожие на объекты PropertyInfo
: их можно использовать для получения и установки значения свойства, и у них есть атрибуты.
Для экземпляров DependencyObject
в WPF TypeDescriptor.GetProperties()
также возвращает прикрепленные свойства. Эти объекты PropertyDescriptor
в этом случае обеспечивают косвенность объектной модели зависимостей, а не отражение.
В конструкторе компонентов можно использовать ICustomTypeDescriptor
или TypeDescriptionProviderAttribute
(и, возможно, некоторые другие методы) для создания ваших собственных объектов PropertyDescriptor
во время выполнения или во время разработки. В любом случае, возможно, что свойства, возвращаемые из Type.GetProperties()
, могут сильно отличаться от свойств, возвращаемых из TypeDescriptor
, в зависимости от контекста.