7

Possible Duplicate:
Impossible recursive generic class definition?

I just discovered that

public class Foo<T> where T : Foo<T>
{

}

is legal. What exactly does it mean? It seems recursive and is it possible to instantiate something like this?

Community
  • 1
  • 1
bradgonesurfing
  • 30,949
  • 17
  • 114
  • 217
  • 10
    These are referred to as "curiously recurring" generic constraints. See also: [Curiouser and curiouser](http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx), by Eric Lippert, it is probably the best explanation you can get. – Kobi Nov 20 '12 at 09:09
  • This is commonly used to get a type reference to the actual class. Example is IComparable, etc. – leppie Nov 20 '12 at 09:11
  • 1
    @AlvinWong, It's not totally useless. You can build tree-like structures like this, by adding properties to Foo which hold your values. Equally, Foo can be inherited, and therefore this constraint will allow any derivative of Foo also. – Matthew Layton Nov 20 '12 at 09:31

1 Answers1

2

I wouldn't say that this is useless. Let's observe the below example how to support fluent syntax. In cases, that you are creating some base implementation in a Parent and would like to provide fluent declarations... you can use this constraint this way

public class Parent<TChild>
    where TChild : Parent<TChild>
{
    public string Code { get; protected set; }

    public TChild SetCode(string code)
    {
        Code = code;
        return this as TChild; // here we go, we profit from a constraint
    }
}

public class Child : Parent<Child>
{
    public string Name { get; protected set; }

    public Child SetName(string name)
    {
        Name = name;
        return this // is Child;
    }
}

[TestClass]
public class TestFluent
{
    [TestMethod]
    public void SetProperties()
    {
        var child = new Child();
        child
            .SetCode("myCode") // now still Child is returned
            .SetName("myName");

        Assert.IsTrue(child.Code.Equals("myCode"));
        Assert.IsTrue(child.Name.Equals("myName"));
    }
}

Please, take it just an example, of how this constraint could be used

Radim Köhler
  • 122,561
  • 47
  • 239
  • 335
  • Interesting example. Not sure I like it - it still feels wrong, but I see that it *could* have some uses... – Grhm Nov 20 '12 at 09:44