2012-11-20 15 views
7

Powiel możliwe:
Impossible recursive generic class definition?Strange C# rodzajowe contraint

Właśnie odkryłem, że

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

} 

jest legalne. Co to dokładnie znaczy? Wydaje się, że rekurencyjne jest i czy możliwe jest utworzenie czegoś takiego w ten sposób: ?

+10

Są one nazywane "ciekawie powtarzającymi się" ogólnymi ograniczeniami. Zobacz także: [Curiouser and curiouser] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx) autorstwa Erica Lipperta, jest to prawdopodobnie najlepsze wytłumaczenie możesz dostać. – Kobi

+0

Jest to powszechnie używane, aby uzyskać odniesienie do klasy rzeczywistej. Przykładem jest IComparable, itp. – leppie

+1

@ AlvinWong, To nie jest całkowicie bezużyteczne. Możesz budować podobne do drzewa struktury, dodając właściwości do Foo, które trzymają twoje wartości. Podobnie, Foo może być dziedziczone, a zatem to ograniczenie pozwoli również na dowolną pochodną Foo. – series0ne

Odpowiedz

2

Nie powiedziałbym, że to jest bezużyteczne. Spójrzmy na poniższy przykład, jak obsługiwać składnię fluent. W przypadkach, które tworzą pewną base wdrożenie w Dominującą i chciałby, aby zapewnić płynne deklaracji ... można użyć tego ograniczenia w ten sposób

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")); 
    } 
} 

Proszę wziąć to tylko przykład, w jaki sposób ten ograniczenie może być używane

+0

Interesujący przykład. Nie jestem pewien, czy mi się podoba - nadal jest źle, ale widzę, że to * może * mieć jakieś zastosowania ... – Grhm

Powiązane problemy