60 votes

comprendre les classes génériques imbriquées en C # avec quiz

Tout en parlant avec un collègue à propos de C#, il m'a montré un code C# que j'ai eu à prédire la sortie de. Ce semblait simple, en premier lieu, mais il n'était pas. Je ne peux pas vraiment comprendre pourquoi C# réagit de cette façon.

Le 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();
    }
}

La sortie est:

System.Boolean
System.Char
System.Int32

Corrigez-moi si je me trompe, mais je comprends qu' o.a est de type bool, car C<T3> hérite B<T3> et B<T2> hérite A<T2>. Et je peux aussi légèrement comprendre qu' o.c est de type int, car le type d' c est T1 qu'il obtient à partir de l'extérieur de la classe (je pense).

Ma tête est sur le point d'exploser quand j'essaie de comprendre pourquoi o.b est de type char. Peut-on expliquer cela à moi?

40voto

Eric Lippert Points 300275

Ce vieux est un puzzle, et il est assez difficile. Quand je l'ai donné à Anders lui-même qu'il n'a pas le droit de réponse la première fois!

Je pense que la version de votre collègue vous a donné est à partir de Cyrus blog:

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

Un peu plus simple version est sur mon blog.

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

La solution à ma version est ici:

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

Brièvement, la raison de la confusion de comportement est que lorsque vous avez un nom qui existe à la fois à l'extérieur de la classe et une classe de base, la classe de base "gagne". C'est, si vous avez:

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

Ensuite, P.X.D.N hérite B.X, pas de P.X. Le puzzle rend types génériques imbriqués de telle manière que la même déclaration peut être nommé par le biais de la "externe" et "base" chemins de la recherche, mais a différentes significations dans chaque car des génériques de la construction.

De toute façon, lire l'explication sur le blog, et si c'est toujours pas clair, demandez à une question plus spécifique.

8voto

CubeSchrauber Points 754

Ok, ma première réponse était fausse. L'imbrication est important:

en o.b.GetType() b est le membre de l'entourage de la classe qui est instancié en tant que B<char> qui hérite de l' A<char> ce qui rend T1 égale à char. Ce n'est pas tout à fait clair, c'est le suivant (manuel de l'instanciation pour 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;
        }
    }
}

Ici, C_bool auraient pu être tirés de A_bool.B_bool ainsi, non? Mais puisque nous sommes imbriqués en A_char qui est préféré.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X