2013-01-09 11 views
59

Während ich mit einem Kollegen über C# sprach, zeigte er mir einen C# -Code, mit dem ich die Ausgabe von C# vorhersagen konnte. Das sah zunächst einfach aus, war es aber nicht. Ich kann nicht wirklich verstehen, warum C# so handelt.Verständnis für verschachtelte generische Klassen in C# mit Quiz

Der Code:

public class A<T1> 
{ 
    public T1 a; 

    public class B<T2> : A<T2> 
    { 
     public T1 b; 

     public class C<T3> : B<T3> 
     { 
      public T1 c; 
     } 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     A<int>.B<char>.C<bool> o = new A<int>.B<char>.C<bool>(); 

     Console.WriteLine(o.a.GetType()); 
     Console.WriteLine(o.b.GetType()); 
     Console.WriteLine(o.c.GetType()); 

     Console.ReadKey(); 
    } 
} 

Die Ausgabe lautet:

System.Boolean 
System.Char 
System.Int32 

mich korrigieren, wenn ich falsch bin, aber ich verstehe, dass o.a vom Typ Bool ist, weil C<T3> erbt von B<T3> und B<T2> inherits von A<T2>. Und ich kann auch leicht verstehen, dass o.c vom Typ int ist, weil der Typ cT1 ist, die es von der äußeren Klasse (denke ich) bekommt.

Mein Kopf explodiert fast, wenn ich versuche herauszufinden, warum o.b vom Typ char ist. Kann mir das jemand erklären?

+38

Ich bin froh, dass ich den Code in Ihrem Unternehmen nicht behalte. – Default

+0

Interessant, aber totaler Overkill für alles Praktische. Ich nehme an, das ist akademisch und nicht für die Arbeit? – JGilmartin

+4

@Default Warum? Weil sie sich gerne auf seltsamen C# -Code quizieren? – Erix

Antwort

40

Dies ist ein altes Puzzle, und es ist ziemlich schwierig. Als ich es Anders selbst gab, bekam er die Antwort beim ersten Mal nicht richtig!

ich denke, die Version Ihr Kollege hat Ihnen von Cyrus Blog ist:

http://blogs.msdn.com/b/cyrusn/archive/2005/08/01/446431.aspx

Eine etwas einfachere Version auf meinem Blog.

http://blogs.msdn.com/b/ericlippert/archive/2007/07/27/an-inheritance-puzzle-part-one.aspx

Die Lösung für meine Version ist hier:

http://blogs.msdn.com/b/ericlippert/archive/2007/07/30/an-inheritance-puzzle-part-two.aspx

Kurz gesagt, der Grund für das verwirrende Verhalten ist, dass, wenn Sie einen Namen, der sowohl in einer äußeren Klasse und einem existiert Basisklasse, die Basisklasse "gewinnt". Das heißt, wenn Sie:

public class B 
{ 
    public class X {} 
} 
public class P 
{ 
    public class X 
    { 
    public class D : B 
    { 
     public class N : X {} 
    } 
    } 
} 

Dann P.X.D.N erbt von B.X, nicht von P.X. Das Puzzle macht verschachtelte generische Typen so, dass dieselbe Deklaration sowohl über die "äußeren" als auch die "Basis" Suchpfade benannt werden kann, aber unterschiedliche Bedeutungen in jedem wegen der generischen Konstruktion hat.

Wie auch immer, lesen Sie die Erklärung in den Blog-Posts, und wenn es immer noch nicht klar ist, stellen Sie eine genauere Frage.

8

Ok, meine erste Antwort war falsch. Die Verschachtelung ist wichtig:

in o.b.GetType() b ist das Mitglied der umgebenden Klasse, die instanziiert wird als B<char>, die von A<char> erbt, was wiederum T1 gleich Char macht. Was ist nicht ganz klar ist die folgende (manuelle Instanziierung für A_int.B_char.C_bool):

public class A_bool 
{ 
    public bool a; 

    public class B_bool : A_bool 
    { 
     public bool b; 
    } 
} 

public class A_char 
{ 
    public char a; 

    public class B_bool : A_bool 
    { 
     public char b; 
    } 
} 

public class A_int 
{ 
    public int a; 

    public class B_char : A_char 
    { 
     public int b; 

     public class C_bool : A_char.B_bool 
     { 
      public int c; 
     } 
    } 
} 

Hier C_bool konnte von A_bool.B_bool auch abgeleitet wurden, nicht wahr? Aber da wir in A_char verschachtelt sind, ist das bevorzugt.

+1

Dann warum ist o.c kein Bool? Weil C von B erbt, die wiederum von A .. –

+1

erbt. Ja, was verwirrend ist, ist der Unterschied zwischen Vererbung und umschließenden Typen. 'C ' ist in 'B ' eingeschlossen, erbt aber von 'B ' – CubeSchrauber

+0

Dies ist eine gute Möglichkeit, die Situation zu veranschaulichen! –

Verwandte Themen