Friday, 10 September 2010

Pseudo-Template Meta-Programming in C#

Not full details here, but I'm writing this post as part-memo to myself, but also in the hope that one or two of you might make a mental bookmark to keep checking back.

In the course of my most recent project, which involve classes which wrap a common data storage mechanism (a bit like DataRows) I encountered a problem which was best solved with a solution called (coining a phrase) 'self-aware' properties.  Assuming all the storage access code is provided in a common base, and using attributes to define the string name of the 'column' (to continue the DataRow analogy) to which a property is mapped:

class X
{
  [MappedProperty("actualvaluename")]

  public string SomeValue
  {
     get
     {
        return base.GetPropertyValue("SomeValue");
     }

  }

}

So far so rudimentary.  However, I wanted my framework to be able to support inheritance, so that a class inheriting from another one not only could inherit it's properties, but also so it could actually override the mappings for a property defined by a base, just by using the same attribute.

Also, what I didn't want to have to do was:

a) Store mapping information in every instance of such a class (to weighty)
b) Write some behemoth registry which keeps track of all the mappings (initialisation problems, potential threading issues, not to mention a nightmare to extend and maintain)

The solution that I have produced takes a few ideas from the ideas laid out by C++ Template Meta-Programming (read this book if you want to know more: http://www.amazon.co.uk/Template-Metaprogramming-Concepts-Techniques-Beyond/dp/0321227255), but of course it all happens at run time - because Templates in C++ are not the same as C# Generics.  It takes advantage of an immensely powerful feature of Extension Methods - generic extension methods (think public static void Foo<T>(this T instance, ...) ),  as well dynamic Generic class instantiation using reflection to achieve the generic recursion required to build the data for each level in the class hierarchy.

All it took was a common base (with practically no methods), a static generic class plus some extension methods - and the C# type engine does the rest for you.

In a future post I will lay out the design, but for now I've run out of time (it's Fathers' day - which as many fathers will know doesn't necessarily mean that Father gets to choose what he does!)

No comments:

Post a Comment