Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get private properties with TypeDescriptor

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.

like image 447
BanditoBunny Avatar asked Oct 26 '11 08:10

BanditoBunny


2 Answers

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

like image 135
Marc Gravell Avatar answered Oct 27 '22 16:10

Marc Gravell


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;
    }
}
like image 3
Harmony Piano Avatar answered Oct 27 '22 14:10

Harmony Piano