10

I happened upon this in an NHibernate class definition:

public class SQLiteConfiguration : PersistenceConfiguration<SQLiteConfiguration>

So this class inherits from a base class that is parameterized by... the derived class?   My head just exploded.

Can someone explain what this means and how this pattern is useful?

(This is NOT an NHibernate-specific question, by the way.)

anon
  • 4,578
  • 3
  • 35
  • 54
  • This is a duplicate of http://stackoverflow.com/questions/3783321/why-does-this-generic-constraint-compile-when-it-seems-to-have-a-circular-referen/3789193#3789193 – Eric Lippert Jan 08 '11 at 05:27
  • Eric: I had cited this SO question below in my comments to Lambert. – anon Jan 08 '11 at 05:33
  • I read this thread quite a while ago but only now came across this specific scenario. I found the thread again by searching for "my head just exploded". LOL. Good thing you wrote that or I may never have found it again. :-) – Nick Spreitzer Apr 08 '11 at 20:44
  • "Curiously Recurring Template Pattern" is such a boring name. I hereby re-christen this pattern as the "Cranial Rupture Template Pattern." – anon Apr 09 '11 at 01:39

2 Answers2

5

That's a funny Curiously Recurring Template Pattern, isn't it?

user541686
  • 205,094
  • 128
  • 528
  • 886
  • Huh. I never, ever thought I would find myself laughing out loud at inheritance syntax. Here's another SO question that is useful: http://stackoverflow.com/questions/1327568/curiously-recurring-template-pattern-and-generics-constraints-c – anon Jan 08 '11 at 03:51
  • Here's another great discussion: http://stackoverflow.com/questions/3783321/why-does-this-generic-constraint-compile-when-it-seems-to-have-a-circular-referen. Also: http://fernandof.wordpress.com/2007/09/23/recursive-generics-restrictions/ – anon Jan 08 '11 at 04:05
2

I have used the same pattern when developing a double linked tree. Each node has 1 parent, and 0-many children

class Tree<T> where T : Tree<T>
{
    T parent;
    List<T> children;
    T Parent { get; set; }
    protected Tree(T parent) 
    {
        this.parent = parent; 
        parent.children.Add(this);
    }
    // lots more code handling tree list stuff
}

implementation

class Coordinate : Tree<Coordinate>
{
    Coordinate(Coordinate parent) : this(parent) { }
    static readonly Coordinate Root = new Coordinate(null);
    // lots more code handling coordinate systems
}

usage

Coordinate A = Coordinate.Root;
Coordinate B = new Coordinate(A);

B.Parent // returns a Coordinate type instead of a Node<>.

So anything that inherits from Tree<> will contain properties for parent and children objects in the appropriate type. This trick is pure magic for me.

John Alexiou
  • 28,472
  • 11
  • 77
  • 133