12
votes

Quel type de béton "rendement retour" de retour?

Quel est le type concret de ce ienumerable code>?

private IEnumerable<string> GetIEnumerable()
{
    yield return "a";
    yield return "a";
    yield return "a";
}


2 commentaires

Ceci est un sucre syntaxique. Beaucoup se passe sous le capot. Le moyen plus rapide de la voir est d'utiliser le réflecteur. Il crée fondamentalement une classe qui conserve un état et renvoie "A" lorsque getNext () ou quelque chose comme ça s'appelle.


@Timwi merci pour la modification :)


3 Réponses :


10
votes

C'est un type généré par le compilateur. Le compilateur génère un ienumerator implémentation qui renvoie trois valeurs "a" et un ienumerable classe squelette qui en fournit l'un d'entre eux dans son getenumerator < / code> méthode.

Le code généré a l'air quelque chose comme ceci *: xxx

ou peut-être, comme le dit Slaks dans sa réponse, le Deux implémentations se retrouvent dans la même classe. J'ai écrit ceci en fonction de ma mémoire agitée de code généré que j'avais examiné auparavant; Vraiment, une classe suffirait, car il n'ya aucune raison que la fonctionnalité ci-dessus nécessite deux.

En fait, viennent y penser, les deux implémentations vraiment devraient tomber dans une seule classe , comme je viens de me souvenir des fonctions qui utilisent des instructions de rendement doivent avoir un type de retour ienumerable ou ienumerator .

Quoi qu'il en soit, je vous laisse effectuer les corrections de code sur ce que j'ai affiché mentalement.

* Ceci est purement à des fins d'illustration; Je ne fais aucune réclamation quant à sa réelle précision. Il est que de démontrer de manière générale comment le compilateur fait ce qu'il fait, sur la base des preuves que j'ai constatées dans mes propres enquêtes.


1 commentaires

De plus, le type généré par le compilateur aura le nom d__0 dans votre exemple. (Oui, le << / code> et > fait partie du nom type . Vous ne pouvez pas écrire un tel nom de type dans C #, mais c'est valable Dans le CLRR.) Le type est imbriqué à l'intérieur du type qui déclare la méthode getienumerable () .



9
votes

Le compilateur générera automatiquement une classe qui implémente à la fois ienumerable et ienumerator (dans la même classe).

Jon Skeet a une explication détaillée .


1 commentaires

Veuillez ajouter les parties pertinentes du lien à votre réponse



3
votes

La mise en œuvre concrète de ienumerable code> renvoyée par la méthode est un type anonyme généré par le compilateur xxx pré>

impressions: p>

YourClass+<GetIEnumerable>d__0


0 commentaires