The missing link in C# generics: TThis

I was talking to a friend of mine (Mike Hurley, who doesn’t have a blog so I can’t properly cite him) and he had an interesting solution to a problem in C# that has nagged me for a while. The problem is with strongly typing generic members to that of a sub-class. Let me explain.

The example he gave me was with ICloneable. ICloneable has a single method Clone, which returns an object. Rather than casting everywhere he decided to take the next logical step, which was to make a generic IClonable.

public interface ICloneable<T> : ICloneable
{
    T Clone();
}

Now to follow this logic you might want to create a ClonableBase class that either provides virtual methods to implement the cloning or has a generic scheme (such as serialization / deserialization) to do the cloning automatically for you.

public abstract class CloneableBase<T> : ICloneable<T>
    where T : ICloneable<T>
{
    object ICloneable.Clone()
    {
        return this.Clone();
    }

    public T Clone()
    {
        T clone = default(T);
        // do clone...
        return clone;
    }
}

The only problem with this is that you have to know what T is. In this case, T is the subclass of this. But there is no way to express TThis in C#. The best you can do is to have the recursive generics like above which when implemented would look like this.

public class Example : CloneableBase<Example>
{
}

While this works just fine in practice it has a few drawbacks. The first is just that it sort of makes your brain hurt a little bit and feels a little wrong. Another reason is that it makes performing reflection and casting much more difficult (though I suppose you could always down cast it into IClonable in this example). And finally it doesn’t actually express the constraint the base class is expecting, meaning you can write invalid code. Consider this:

public class Example : CloneableBase<Foo>
{
}

This would build just as easily but is clearly, totally wrong. There is no way in C# to properly express this constraint correctly. Not yet at least. Mike was recommending adding a TThis feature to the language. The corresponding code with this feature might look like this.

public abstract class CloneableBase : ICloneable<TThis>
{
    object ICloneable.Clone()
    {
        return this.Clone();
    }

    public TThis Clone()
    {
        TThis clone = default(TThis);
        // do clone...
        return clone;
    }
}

public class Example : CloneableBase
{
}

Where TThis is literally the type of the instance, or the Type about to be instantiated. I’m not sure how you would retrofit this to the current generics system but it seems plausible. If you’re not sure how common or useful this feature would be take a look at CSLA and see BusinessBase<T> among others.

Design Patterns as External DSLs

I’ve been thinking about how you might layer DSLs into ever increasing abstractions and how you might combine multiple DSLs with ease. These are problems I definitely don’t have the answers to just yet but while looking at how Axum is coming along I can’t help but feel like Axum is a language designed specifically to help you write code that conforms to a specific design pattern. I mean it’s still .net under the hood (I think) which is no more or less async safe than what you or I can write manually but it constrains you such that you cannot create bad asynchronous code (or should make it much harder at least!).

This is really fascinating to me, since intuitively it feels like a really good idea but I don’t quite get how it can coexist with other types of development or DSLs right off the bat. I also think it reinforces the idea that constraint, at times, can be more powerful than flexibility. One of the things about “dynamic” languages that I’m not totally convinced about is the how it feels like the wild-wild-west, anything goes type of programming. Sometimes having limiting constructs can actually more powerful and that is not appreciated enough, I don’t think.

Anyway, I was just trying to picture a world where you had one DSL where you designed various models for your application and another DSL where consumed them in a specific design pattern. This seems feasible I’m still trying to figure out how you might “glue” them together. Probably using templates somehow. Food for thought, if anyone has any insight or ideas leave a comment!

DSL DevCon 2009 Videos

The videos for the presentations at DSL DevCon 2009 are now online. You have to scroll down a ways to get to them but here is the link:

http://msdn.microsoft.com/en-us/oslo/videos.aspx

If you don’t have time to watch all of these then at least check out the video that everyone is talking about from the Intentional Software team:

http://msdn.microsoft.com/en-us/oslo/dd727740.aspx

enjoy!