I want to create a method that allows me to change arbitrary properties of classes that derive from my base class, the result should look like this: SetPropertyValue("size.height", 50); – where size is a property of my derived class and height is a property of size.
I'm almost done with my implementation but there's one final obstacle that I want to solve before moving on, to describe this I will first have to explain my implementation a bit:
Properties that can be modified are decorated with an attribute
There's a method in my base class that searches for all derived classes and their decorated properties
For each property I generate a "property modifier", a class that contains 2 delegates: one to set and one to get the value of the property.
Property Modifiers are stored in a dictionary, with the name of the property as key
In my base class, there is another dictionary that contains all property-modifier-dictionaries, with the Type of the respective class as key.
What the SetPropertyValue method does is this:
Get the correct property-modifier-dictionary, using the concrete type of the derived class (<- yet to solve)
Get the property modifier of the property to change (e.g. of the property size)
Use the get or set delegate to modify the property's value
Some example code to clarify further:
private static Dictionary<RuntimeTypeHandle, object> EditableTypes; //property-modifier-dictionary
protected void SetPropertyValue<T>(EditablePropertyMap<T> map, string property, object value) {
var property = map[property]; // get the property modifier
property.Set((T)this, value); // use the set delegate (encapsulated in a method)
}
In the above code, T is the Type of the actual (derived) class. I need this type for the get/set delegates. The problem is how to get the EditablePropertyMap<T> when I don't know what T is.
My current (ugly) solution is to pass the map in an overriden virtual method in the derived class:
public override void SetPropertyValue(string property, object value) {
base.SetPropertyValue((EditablePropertyMap<ExampleType>)EditableTypes[typeof(ExampleType)], property, value);
}
What this does is: get the correct dictionary containing the property modifiers of this class using the class's type, cast it to the appropiate type and pass it to the SetPropertyValue method.
I want to get rid of the SetPropertyValue method in my derived class (since there are a lot of derived classes), but don't know yet how to accomplish that. I cannot just make a virtual GetEditablePropertyMap<T> method because I cannot infer a concrete type for T then. I also cannot acces my dictionary directly with a type and retrieve an EditablePropertyMap<T> from it because I cannot cast to it from object in the base class, since again I do not know T.
I found some neat tricks to infere types (e.g. by adding a dummy T parameter), but cannot apply them to my specific problem. I'd highly appreciate any suggestions you may have for me.