comprendre les classes génériques nestedes en C # avec le quiz

En discutant avec un collègue à propos de C #, il m’a montré du code C # que je devais prédire la sortie de. Cela semblait simple en premier lieu, mais ce n’était pas le cas. Je ne peux pas vraiment comprendre pourquoi C # agit de cette façon.

Le code:

public class A { public T1 a; public class B : A { public T1 b; public class C : B { public T1 c; } } } class Program { static void Main(ssortingng[] args) { A.B.C o = new A.B.C(); Console.WriteLine(oaGetType()); Console.WriteLine(obGetType()); Console.WriteLine(ocGetType()); Console.ReadKey(); } } 

La sortie est la suivante:

 System.Boolean System.Char System.Int32 

Corrigez-moi si je me trompe, mais je comprends que oa est de type bool car C hérite de B et B hérite de A . Et je peux aussi comprendre légèrement que oc est de type int car le type de c est T1 qu’il obtient de la classe externe (je pense).

Ma tête explose presque quand j’essaie de comprendre pourquoi ob est de type char. Quelqu’un peut m’expliquer cela?

C’est un vieux casse-tête, et c’est assez difficile. Quand je l’ai donné à Anders lui-même, il n’a pas eu la bonne réponse la première fois!

Je pense que la version que votre collègue vous a donnée provient du blog de Cyrus:

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

Une version légèrement plus simple 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 la suivante:

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

En bref, la raison du comportement déroutant est que lorsque vous avez un nom qui existe à la fois dans une classe externe et une classe de base, la classe de base “gagne”. C’est-à-dire si vous avez:

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

Ensuite, PXDN hérite de BX , pas de PX . Le puzzle crée des types génériques nesteds de telle manière que la même déclaration peut être nommée via les chemins de recherche “externes” et “de base”, mais a des significations différentes en raison de la construction générique.

Quoi qu’il en soit, lisez les explications sur les articles du blog et, si ce n’est toujours pas clair, posez une question plus précise.

Ok, ma première réponse était fausse. La nidification est importante:

dans obGetType() b est le membre de la classe environnante qui est instanciée comme B qui hérite de A qui à son tour rend T1 égal à char. Ce qui n’est pas tout à fait clair est la suivante (instanciation manuelle 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 aurait également pu être dérivé de A_bool.B_bool, non? Mais comme nous sums nesteds dans A_char cela est préférable.