2012-11-20 15 views
7

Eventuali duplicati:
Impossible recursive generic class definition?Strano C# contraint generico

Ho appena scoperto che

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

} 

è legale. cosa significa esattamente? Sembra ricorsivo ed è possibile creare un'istanza di qualcosa come in questo modo?

+10

Questi sono chiamati vincoli generici "curiosamente ricorrenti". Vedi anche: [Curioso e curioso] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curiouser.aspx), di Eric Lippert, è probabilmente la migliore spiegazione Puoi prendere. – Kobi

+0

Questo è comunemente usato per ottenere un riferimento di tipo alla classe effettiva. L'esempio è IComparable, ecc. – leppie

+1

@AlvinWong, non è del tutto inutile. Puoi costruire strutture simili ad alberi, aggiungendo proprietà a Foo che contiene i tuoi valori. Allo stesso modo, Foo può essere ereditato, e quindi questo vincolo consentirà anche qualsiasi derivato di Foo. – series0ne

risposta

2

Non direi che questo è inutile. Osserviamo l'esempio seguente come supportare la sintassi fluente. Nei casi, che si sta creando un po 'di base implementazione in un genitoree vorrebbe fornire dichiarazioni fluente ... è possibile utilizzare questo vincolo in questo modo

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

Si prega di tenere è solo un esempio, di come questo potrebbe essere utilizzato il vincolo

+0

Esempio interessante. Non sono sicuro che mi piaccia - sembra ancora sbagliato, ma vedo che * potrebbe * avere alcuni usi ... – Grhm