Comment fonctionne foreach lorsque vous parcourez les résultats d’une fonction?

Supposons que j’ai le code suivant:

foreach(ssortingng str in someObj.GetMySsortingngs()) { // do some stuff } 

someObj.GetMySsortingngs() sera-t-il appelé à chaque itération de la boucle? Serait-il préférable de procéder comme suit:

 List mySsortingngs = someObj.GetMySsortingngs(); foreach(ssortingng str in mySsortingngs) { // do some stuff } 

?

La fonction n’est appelée qu’une seule fois, pour renvoyer un IEnumerator ; après cela, la méthode MoveNext() et la propriété Current sont utilisées pour parcourir les résultats:

 foreach (Foo f in GetFoos()) { // Do stuff } 

est un peu équivalent à:

 using (IEnumerator iterator = GetFoos().GetEnumerator()) { while (iterator.MoveNext()) { Foo f = iterator.Current; // Do stuff } } 

Notez que l’iterator est éliminé à la fin – ceci est particulièrement important pour disposer des ressources des blocs d’iterators, par exemple:

 public IEnumerable GetLines(ssortingng file) { using (TextReader reader = File.OpenText(file)) { ssortingng line; while ((line = reader.ReadLine()) != null) { yield return line; } } } 

Dans le code ci-dessus, vous voulez vraiment que le fichier soit fermé lorsque vous avez terminé l’itération, et le compilateur implémente astucieusement IDisposable pour que cela fonctionne.

Non .. la fonction sera appelée une fois pour obtenir le IEnumerable .. et il y aura ensuite un appel répété à MoveNext and Current.

GetMySsortingngs () renvoie un object de type IEnumerable. Le runtime sait comment gérer cela. Il appelle IEnumerable.GetEnumerator () puis, sur cet object énumérateur, appelle MoveNext () et Current.

Juste pour arrondir la question au cas où vous tombez dans un “tous pour sont les mêmes”; for (int x = 0; x