2012-11-20 13 views
7

Mögliche Duplizieren:
Impossible recursive generic class definition?Seltsam C# generic contraint

ich gerade entdeckt, dass

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

} 

legal ist. Was genau bedeutet es? Es scheint rekursiv und ist es möglich, etwas instanziieren so?

+10

Diese werden als "seltsam wiederkehrende" generische Constraints bezeichnet. Siehe auch: [Neugieriger und neugieriger] (http://blogs.msdn.com/b/ericlippert/archive/2011/02/03/curiouser-and-curious.aspx), von Eric Lippert, ist es wahrscheinlich die beste Erklärung du kannst bekommen. – Kobi

+0

Dies wird häufig verwendet, um eine Typreferenz auf die tatsächliche Klasse zu erhalten. Beispiel ist IComparable usw. – leppie

+1

@AlvinWong, Es ist nicht völlig nutzlos. Sie können baumähnliche Strukturen wie diese erstellen, indem Sie Foo Eigenschaften hinzufügen, die Ihre Werte enthalten. Gleichermaßen kann Foo vererbt werden, und daher wird diese Einschränkung jede Ableitung von Foo ebenfalls erlauben. – series0ne

Antwort

2

Ich würde nicht sagen, dass dies nutzlos ist. Lassen Sie uns das folgende Beispiel beobachten, wie man fließende Syntax unterstützt. In den Fällen, dass Sie einige base Implementierung in einem Eltern schaffen und möchte fließend Erklärungen liefern ... können Sie diese Einschränkung auf diese Weise verwenden

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

Bitte, nehmen Sie es nur ein Beispiel, wie diese Constraint könnte verwendet werden

+0

Interessantes Beispiel. Ich bin mir nicht sicher, ob ich es mag - es fühlt sich immer noch falsch an, aber ich sehe, dass es * etwas nutzen könnte ... – Grhm