How to infer the type of a derived class in base class?

Posted by enzi on Stack Overflow See other posts from Stack Overflow or by enzi
Published on 2011-02-28T15:24:35Z Indexed on 2011/02/28 15:24 UTC
Read the original article Hit count: 206

Filed under:
|
|

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.

© Stack Overflow or respective owner

Related posts about c#

Related posts about generics