Reflection Type vs TypeDescriptor - c#

Lately I have been using reflection to work in my project, and I have the current question.
While in Type.GetProperties(Flags), we can filter the properties we get using 'Flags'; in TypeDescriptor.GetProperties(), we don't.
In type.GetProperties I can filter to get only properties not inherited.
Is it possible to do the same with TypeDescriptor.GetProperties() (only properties not inherited)?
Thank you

No, you can't.
The TypeDescriptor.GetProperties() is used to get PropertyDescriptor instances with possibility to filter using specific Attributes.
The Type.GetProperties() is used to get PropertyInfo instances with possibility to filter using specific BindingFlags.

Related

Read properties from anonymous object

I am generating a OkObjectResult that has anonymous properties:
When i receive data i can see the properties in the debugger / quickwatch:
I am unable to get the property names out of my anonymous object.
Is there a "simple" way?
The solution i found was to search for my desired properties via reflection. Is this the way to to it?
Edit: Even whey using dynamic i am not able to get the properties.
Instead of var use dynamic type for okResult. Thereafter, you can access your properties like: okResult.data and so on...
Update: As Daisy pointed out below, you will need InternalsVisibleTo because the generated anonymous type is internal, and the dynamic binder checks that.

How to Individuate an element of a list using reflection?

I have a List<T> of element and a PropertyInfo with a list of the property of T.
How can I identify a single property of an element in a loop ?
Ideally :
List<T>[i].PropertyInfo[y].Name
If i understood the question currently and you're looking to match the two collections, then you could use the type of the property info(Has a property type Property) and the typeof(T).
For efficiency i would recommend creating a dynamic method that would be cached for future usage.
If you are looking for the type of the properties, you must use the property:
PropertyInfo.PropertyType
I solved the problem using a solution like the one in the post "Get property value from string using reflection in C#".

In C#, How to Change the DefaultValue Attribute of a Property in a Class that is Not Inheritable?

Here is my situation:
I have a 3rd party Component Control which I successfully inherited,
and now I am doing some custumization to it.
Part of that customization, is to change the DefaultValues of some properties it has.
So far it all went OK,
but this control has some "Sub" Classes in it, that I want to change their propeties' DefaultValues too.
By "Sub" Classes I mean:
Let's say my control is called SomeControl,
so it has properties in it, but it also has a property that is expandable,
like: SomeControl.Rows,
The .Rows property returns a RowCollection which has its own properties.
So this is what I mean by "Sub" Class (please correct me if there's a better term for this)
In any case, If I want to change some DefaultValues in the RowCollection class,
I need to inherit it too.
The propblem is that RowCollection's Ctor is internal, so I cannot inherit that class.
So is there any other way for me to change the DefaultValue attribute for a property in a class that I cannot inherit?
Maybe via reflection?
I nee to change it for an instance(object) that I have existing - one instance,
and not for the class in general.. (since after 1 object is created from it, no more are created..)
Thank you
Summary: I don't think it is possible to do this via reflection, but here is how I would do it:
First get the property you want:
var defValAttr = typeof (SomeControl.RowCollection)
.GetProperty("yourProperty")
.GetCustomAttributes(typeof(DefaultValueAttribute), false)
.First()
as DefaultValueAttribute;
DefaultValueAttribute has a .Value property, which is readonly. To modify it you need reflection again to change the private .value field:
var valueField= typeof (DefaultValueAttribute)
.GetField("value", BindingFlags.NonPublic
| BindingFlags.GetField
| BindingFlags.Instance);
valueField.SetValue(defValAttr, yourNewDefaultValue);
I have not tested this myself, but as far as I know this will not work. The objects returned by GetCustomAttributes are not the actual attributes; you can get the values of the real attributes this way, but you cannot change them. (see Can attributes be added dynamically in C#?)
However, even if this would work, it would change the DefaultValue for all instances of SomeControl.Rows, whether they are within your custom derived control or in the base control. There is no way to change only the DefaultValue of a single instance, since the this value is stored only once per class, not once per instance. It would be very wasteful if there was a copy of each attribute for each instance of an object.
So in conclusion, I don't think there is a way to do this.
As an alternative, you could decompile the third-party assembly and add your own assembly with InternalsVisibleTo, that way you can access the internal constructor.
Addendum: There may still be a way to do this, depending on what sort of attribute you want to change. The attributes accessible via reflection are as I said probably unchangeable. However The visual studio editor and the whole WPF component model actually uses a TypeDescriptor to manage attributes on top of the basic attribute system built into the language. You may be able to change the attributes used by the TypeProvider, and if code later accesses the attributes via TypeDescriptor, it may see the changed values.
The following is again untested:
var instanceOfRow = instanceOfYourControl.Rows;
var defValAttr = TypeDescriptor
.GetProperties(instanceOfRow)["yourProperty"]
.Attributes[typeof (DefaultValueAttribute)]
as DefaultValueAttribute;
var valueField= typeof (DefaultValueAttribute)
.GetField("value", BindingFlags.NonPublic
| BindingFlags.GetField
| BindingFlags.Instance);
valueField.SetValue(defValAttr, yourNewDefaultValue);

Using Impromptu-Interface to obtain the type of a property

I've got a complex solution where part of the problem is model binding from a HTML form to a series of database backed and relatively complex Entity Framework DbSets.
The thing is, we have an EF defined domain model that encapsulates everything we'd need to know about the data we're capturing; but the admins of the project want to be able to make a questionnaire-like form, that allows them to choose any of the members of this domain.
Anyway, that's not the problem as such, as it largely works, at least it works very well for simple members, strings, dates, bools and so on. The tricky part was managing members that have multiple fields, such as an Address object.
A solution has been to use Reflection to set the value of the domain that we receive from the form post, but of course that has its overhead and I'm driven to find a nicer way of doing things; In my research I found out about the 'Impromptu interface' project which promises a lot of speed increase over Reflection, but I have one simple problem.
It's all well and good to Get and Set properties:
var val = Impromptu.InvokeGet(domain, "fieldName");
Impromptu.InvokeSet(domain, "fieldName", value);
But what I need to do is to find the Type of the property.
So far I can still only see how to do that with Reflection:
PropertyInfo pi = domain.GetType().GetProperty("Name", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance);
if (pi.GetValue(domain) is IMyInterface)
{
// ? profit
}
So: Is it possible to do this with Impromptu?
I need to cast the property to my Interface as it has members that convert html form posts into my EF objects.
The general question you ask, can I use ImpromptuInterface to query property types, the answer is no, the DLR doesn't have the function, reflection is it.
However, the example you give using reflection isn't testing the property type, it's testing the runtime type of the value so that would still work with Impromptu without reflection.
var val = Impromptu.InvokeGet(domain, "fieldName");
if(val is IMyInterface){
// ? profit
}
Also if you only want properties look at FastMember. It choose the fastest access mechanism based on the type of object.

Filter properties returned by TypeDescriptor.GetProperties() depending on the class they are declared in

Hey guys. I have the following situation.
I want to use a TypeDescriptor to get the properties of a certain type. The type's depth in the inheritance hierarchy may vary. I only want to get the properties declared in the type itself and not in its parents (base). The problem is that when I call TypeDescriptor.GetProperties() it would return everything declared up the inheritance hierarchy up to Object.
I only saw that I can filter the output by Attributes, but I don't want to add another attribute to the properties in my types just for this. Getting them through reflection and not using TypeDescriptor would do what I want, but is not an option for me, because some of the properties will be added dynamically to the type at some point.
Any ideas? If the question is not clear I could provide an example.
You can filter the properties using the ComponentType property :
var properties = from p in TypeDescriptor.GetProperties(x).Cast<PropertyDescriptor>()
where p.ComponentType == x.GetType()
select p;
Can't you just modify the implementation of ICustomTypeDescriptor to reflect your desired behavior?

Categories