views:

274

answers:

2

I can't figure out the use for this code. Of what use is this pattern?

[code repeated here for posterity]

public class Turtle<T> where T : Turtle<T>
{
}
A: 

There is no use that I can see. Basically, it's the same as

public class Turtle
{
}
AngryHacker
It's not the same because in the code given, `Turtle` cannot be instantiated.
strager
Yes it can... see Marc Gravell's comment here http://stackoverflow.com/questions/194484/whats-the-strangest-corner-case-youve-seen-in-c-or-net/1332344#1332344
Thomas Levesque
@Levesque, And see RCIX's comment following.
strager
My question is where does it have any use?
RCIX
Something just occured to me. You can subclass `Turtle` and instantiate that but you can't instantiate a copy of `Turtle` itself.
RCIX
@RCIX, But can you subclass Turtle? Doesn't it require a generic parameter? With generics, you are creating a type, not a "copy" or instance.
strager
@strager : Yes, you can. Look at Marc's comment, he gives an example.
Thomas Levesque
Ah, I misunderstood the comments to that answer. Sorry!
strager
+9  A: 

This pattern essentially allows you to refer to a concrete subclass within the parent class. For example:

public abstract class Turtle<T> where T : Turtle<T>
{
    public abstract T Procreate();
}

public class SeaTurtle : Turtle<SeaTurtle>
{
    public override SeaTurtle Procreate()
    {
        // ...
    }
}

Versus:

public abstract class Turtle
{
    public abstract Turtle Procreate();
}

public class SnappingTurtle : Turtle
{
    public override Turtle Procreate()
    {
        // ...
    }
}

In the former, it's specified that a SeaTurtle's baby will be a SeaTurtle.

dahlbyk
Do you think, this kind of thing would not be required, if there is support for contra variance?
shahkalpesh
It's got more uses. It may implement interfaces for the subclass. Like, in Java, `java.lang.Enum` uses the pattern to implement `java.lang.Comparable` for the subclass. I'm sure C# has something similar.
Johannes Schaub - litb
There are certainly other uses, but they all involve the parent class needing to use the type of its subclass. Regarding implementation of interfaces, you have two choices: implement the interface for T or Turtle<T>. IComparable<T> would only let you compare items of the same subclass, where IComparable<Turtle<T>> would let you compare any Turtle. And since .NET 4.0's IComparable<T> will be contravariant in T, you will be able to use an IComparable<Turtle<T>> as an IComparable<T> because T : Turtle<T>.
dahlbyk