Получить частные свойства с TypeDescriptor - PullRequest
4 голосов
/ 26 октября 2011

Я хотел бы получить приватные свойства класса, используя TypeDescriptor в c #.

Пока звоню

TypeDescriptor.GetProperties(myType);

возвращает только открытые, нестатические свойства.

Я не нашел способа повлиять на GetProperties или GetProvider методы, чтобы заставить их возвращать отличные от «по умолчанию» (публичные, нестатические) члены.

Пожалуйста, не предлагайте рефлексию (я хорошо осведомлен о BindingFlags), если она не дает мне PropertyDescriptor объект.

Ответы [ 2 ]

7 голосов
/ 26 октября 2011

Для этого вам нужно написать и зарегистрировать пользовательский TypeDescriptionProvider, который использует использование отражения. Однако вы, безусловно, можете сделать это - вы даже можете иметь PropertyDescriptor экземпляров, которые фактически взаимодействуют с полями (а не со свойствами). Вам также, вероятно, потребуется написать собственную реализацию bespke PropertyDescriptor, поскольку ReflectPropertyDescriptor - это internal (возможно, вы можете использовать отражение для получения этого). В конечном счете, вам придется использовать отражение для реализации , но вы можете выполнить требование, чтобы TypeDescriptor.GetProperties(Type) возвращало PropertyDescriptor необходимых вам экземпляров.

Вы можете сделать это и для типов вне вашего контроля. Однако следует подчеркнуть, что ваши намерения необычны.

Если вы использовали перегрузку .GetProperties(instance), то вы также можете сделать это, внедрив ICustomTypeDescriptor, что проще, чем полная TypeDescriptionProvider.

Пример подключения специализированного провайдера см. HyperDescriptor

3 голосов
/ 19 октября 2012

Вы можете создать свой собственный CustomPropertyDescriptor, который получает информацию от PropertyInfo.

Недавно мне нужно получить PropertyDescriptorCollection закрытых свойств.

После того, как я использовал type.GetProperties(BindingFlags. Instance | BindingFlags.NonPublic) чтобы получить непубличные свойства, я использую следующий класс для создания соответствующего PropertyDescriptor.

class CustomPropertyDescriptor : PropertyDescriptor
{
    PropertyInfo propertyInfo;
    public CustomPropertyDescriptor(PropertyInfo propertyInfo)
        : base(propertyInfo.Name, Array.ConvertAll(propertyInfo.GetCustomAttributes(true), o => (Attribute)o))
    {
        this.propertyInfo = propertyInfo;
    }
    public override bool CanResetValue(object component)
    {
        return false;
    }

    public override Type ComponentType
    {
        get
        {
            return this.propertyInfo.DeclaringType;
        }
    }

    public override object GetValue(object component)
    {
        return this.propertyInfo.GetValue(component, null);
    }

    public override bool IsReadOnly
    {
        get
        {
            return !this.propertyInfo.CanWrite;
        }
    }

    public override Type PropertyType
    {
        get
        {
            return this.propertyInfo.PropertyType;
        }
    }

    public override void ResetValue(object component)
    {
    }

    public override void SetValue(object component, object value)
    {
        this.propertyInfo.SetValue(component, value, null);
    }

    public override bool ShouldSerializeValue(object component)
    {
        return false;
    }
}
...