使用TypeDescriptor获取私有属性

时间:2011-10-26 08:52:41

标签: c# reflection private-members typedescriptor

我想在c#中使用 TypeDescriptor 获取该类的私有属性。

到目前为止致电

TypeDescriptor.GetProperties(myType);

仅返回公共的非静态属性。

我还没有找到办法如何影响 GetProperties GetProvider 方法来强制他们返回“默认”(公共,非静态)成员以外的其他方式。< / p>

请不要建议反射(我很清楚BindingFlags),除非它给我一个 PropertyDescriptor 对象。

2 个答案:

答案 0 :(得分:7)

要做到这一点,您必须编写并注册 使用反射的自定义TypeDescriptionProvider。但是,您当然可以这样做 - 您甚至可以拥有实际与字段(而不是属性)对话的PropertyDescriptor个实例。您可能还需要编写自己的bespke PropertyDescriptor实现,因为ReflectPropertyDescriptorinternal(您可以使用反射来获取它)。最终, 必须使用反射进行实现,但您可以达到TypeDescriptor.GetProperties(Type)返回{{1}的要求你想要的实例。

您也可以为控件之外的类型执行此操作。但是,应该强调的是,你的意图是不寻常的。

如果您使用PropertyDescriptor重载,那么您也可以通过实施比.GetProperties(instance)更简单的ICustomTypeDescriptor来实现此目的。

有关挂钩定制提供商的示例,请参阅HyperDescriptor

答案 1 :(得分:3)

您可以创建自己的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;
    }
}