Get private properties with TypeDescriptor

3.4k views Asked by At

I would like to get private properties of the class using TypeDescriptor in c#.

So far calling

TypeDescriptor.GetProperties(myType);

returns only public, non-static properties.

I have not found a way how to influence GetProperties or GetProvider methods to force them to return other than "default" (public, non-static) members.

Please do not suggest reflection (I am well aware of BindingFlags) unless it gives me a PropertyDescriptor object.

2

There are 2 answers

3
Marc Gravell On BEST ANSWER

To do that you would have to write and register a custom TypeDescriptionProvider that does use reflection. You can certainly, however, do this - you can even have PropertyDescriptor instances that actually talk to fields (instead of properties). You will also probably need to write your own bespke PropertyDescriptor implementation since ReflectPropertyDescriptor is internal (you could perhaps use reflection to obtain that). Ultimately, you will have to use reflection for the implementation, but you can achieve the requirement that TypeDescriptor.GetProperties(Type) returns PropertyDescriptor instances that you want.

You can do this for types outside your control, too. It should be stressed, however, that your intent is unusual.

If you were using the .GetProperties(instance) overload, then you can also do this by implementing ICustomTypeDescriptor which is simpler than a full TypeDescriptionProvider.

For an example of hooking a bespoke provider, see HyperDescriptor

0
Harmony Piano On

You may create your own CustomPropertyDescriptor which gets the info from PropertyInfo.

Recently I need to get the PropertyDescriptorCollection of nonpublic properties.

After I used type.GetProperties(BindingFlags. Instance | BindingFlags.NonPublic) to get the nonpublic properties, then I use the following class to create the corresponding 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;
    }
}