62 votes

La compréhension du problème C# inférence de type, comme décrit dans la spécification du langage

Le langage C# spécification décrit l'inférence de type dans la Section §7.5.2. Il y a un détail que je ne comprends pas. Considérons le cas suivant:

// declaration
void Method<T>(T obj, Func<string, T> func);

// call
Method("obj", s => (object) s);

Microsoft et Mono C# compilateurs de déduire correctement T = object, mais ma compréhension de l'algorithme dans le cahier des charges donnerait T = string , puis l'échec. Voici comment je comprends bien:

La première phase

  • Si Ei est une fonction anonyme, un paramètre explicite l'inférence de type (§7.5.2.7) est faite à partir de l'Ie à Ti

    ⇒ a aucun effet, parce que l'expression lambda n'a pas explicite des types de paramètres. Droit?

  • Si, au contraire, l'Ie a un type U et xi est un paramètre de valeur alors une limite inférieure de l'inférence est fabriqué à partir de U en Ti.

    ⇒ le premier paramètre est de type statique string, donc cela ajoute de la string à la baisse des valeurs limites pour T, droite?

La deuxième phase

  • Toutes les interprétations variables de type Xi qui ne dépendent (§7.5.2.5) toutes les Xj sont fixes (§7.5.2.10).

    T est non fixée; T ne dépend de rien... si T devrait être fixé, à droite?

§7.5.2.11 de Fixation

  • L'ensemble des candidats types Uj commence comme l'ensemble de tous les types de l'ensemble de limites pour Xi.

    ⇒ { string (limite inférieure) }

  • Ensuite, nous examinons chaque liés à Xi: [...] Pour chaque limite inférieure de l'U de Xi tous les types Uj qui, elle, n'est pas une conversion implicite de U sont retirés de l'ensemble candidat. [...]

    ⇒ ne pas enlever quoi que ce soit à partir de l'ensemble candidat, droite?

  • Si parmi les candidats restants types Uj il existe un unique type de V à partir de laquelle il y a une conversion implicite à tous les autres candidats types, alors Xi est fixé à V.

    ⇒ Car il n'y a qu'un seul candidat type, c'est vacuously vrai, alors Xi est fixé string. Droit?


Alors, où vais-je tort?

41voto

Eric Lippert Points 300275

Mise à JOUR: Mon enquête initiale sur le bus, ce matin, était incomplète et erronée. Le texte de la première phase de spécification est correct. La mise en œuvre est correcte.

La spécification est mauvaise en ce qu'il obtient de l'ordre des événements de mal dans la deuxième phase. Nous devrions être en précisant que nous faire sortie les inférences de type avant de nous résoudre le non-dépendant de paramètres.

L'homme, ce genre de choses est compliqué. J'ai réécrit cette section de la spécification plus de fois que je m'en souvienne.

J'ai vu ce problème avant, et j'ai distinctement rappeler que faire des révisions telles que le terme incorrect "variable de type" a été remplacé partout par "type de paramètre". (Paramètres de Type ne sont pas des emplacements de stockage dont le contenu peut varier, de sorte qu'il n'a pas de sens de les appeler des variables.) Je pense que dans le même temps, j'ai noté que la commande a été mauvais. Probablement ce qui s'est passé nous avons accidentellement transporté une ancienne version de la spécification sur le web. Beaucoup d'excuses.

Je vais travailler avec Mads pour obtenir la spécification de mise à jour pour correspondre à la mise en œuvre. Je pense que la formulation correcte de la deuxième phase devrait aller quelque chose comme ceci:

  • Si non fixées, les paramètres de type existe pas, alors l'inférence de type réussit.
  • Sinon, s'il existe un ou plusieurs arguments de l'Ie avec paramètre correspondant du type Ti tels que le type de sortie de l'Ie, avec type Ti contient au moins un non fixées paramètre de type Xj, et aucun des types d'entrée de l'Ie, avec type Ti contient toutes les interprétations paramètre de type Xj, puis une sortie de l'inférence de type est faite à partir de toutes ces Ei Ti.

Si oui ou non l'étape précédente fait une inférence, nous doit maintenant fixer au moins un paramètre de type, comme suit:

  • S'il existe un ou plusieurs paramètres de type Xi tels que Xi est non fixées, et Xi est non vide de définir des limites, et Xi ne dépend pas d'une Xj chaque Xi est fixe. Si une fixation de l'opération échoue, alors l'inférence de type échoue.
  • Sinon, s'il existe un ou plusieurs paramètres de type Xi tels que Xi est non fixées, et Xi est non vide de définir des limites, et il y a au moins un paramètre de type Xj qui dépend de la Xi chaque Xi est fixe. Si une fixation de l'opération échoue, alors l'inférence de type échoue.
  • Sinon, nous sommes incapables de faire des progrès et il y a non paramètres. L'inférence de Type échoue.

Si l'inférence de type ni échec, ni réussit ensuite, la deuxième phase est répétée.

L'idée ici est que nous voulons nous assurer que l'algorithme ne va jamais dans une boucle infinie. À chaque répétition de la deuxième phase, il réussit, ne parvient pas, ou fait des progrès. Il ne peut pas en boucle plus de fois qu'il y a des paramètres de type, à fixer les types.

Merci pour avoir porté à mon attention.

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