C# yield: tutoriel pas à pas sur les collections paresseuses

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Pourquoi avez-vous besoin de yield en C# ? Le secret des collections paresseuses



Imaginez : vous écrivez une méthode qui doit retourner une liste de nombres de 1 à un million. La première chose qui vient à l'esprit est de créer un List<int>, de le remplir et de le retourner. Mais que faire si le code appelant ne veut que les 10 premiers éléments ? Vous avez quand même passé du temps à créer un million d'objets, occupé de la mémoire – et tout cela pour rien.



C'est là qu'intervient le mot-clé yield en C#. Ce n'est pas seulement du sucre syntaxique, mais un outil puissant pour créer des séquences paresseuses (lazy). Dans cet article, nous allons décortiquer yield return et yield break avec des exemples réels, comprendre comment ils fonctionnent sous le capot, et apprendre à les utiliser dans le développement quotidien.



Ce tutoriel est basé sur une question réelle de Stack Overflow qui a recueilli des milliers de vues. Nous l'avons adapté pour un contenu éducatif, en ajoutant des exemples de code C# pas à pas et des conseils pratiques utiles.



Qu'est-ce que yield en C# ? En termes simples



yield est un mot-clé contextuel en C# qui indique au compilateur : « Cette méthode est un itérateur ». Lorsque vous écrivez yield return, la méthode n'exécute pas tout d'un coup. Au lieu de cela, elle retourne les éléments un par un, lorsque le code appelant les demande. C'est ce qu'on appelle l'exécution paresseuse.



Contrairement à un return normal qui termine la méthode, yield return met la méthode en pause, mémorise son état et retourne l'élément courant. Lors du prochain appel, la méthode reprend là où elle s'était arrêtée.



Syntaxe : yield return et yield break



En C#, il existe deux formes de yield :



  • yield return – retourne l'élément suivant de la séquence.
  • yield break – termine immédiatement l'itération (comme break dans une boucle).


La méthode qui utilise yield doit retourner l'un de ces types :

  • IEnumerable<T>
  • IEnumerable
  • IAsyncEnumerable<T> (à partir de C# 8.0)
  • IEnumerator<T> ou IEnumerator


Premier exemple : du simple au complexe



Écrivons un itérateur très simple qui génère les nombres de 1 à 5 :



public static IEnumerable<int> GetNumbers(){    yield return 1;    yield return 2;    yield return 3;    yield return 4;    yield return 5;}

// Utilisation :foreach (int number in GetNumbers()){ Console.WriteLine(number);}


Sortie :

12345


À première vue, cela ressemble à une liste normale. Mais la différence est énorme : chaque élément est généré uniquement lorsque foreach le demande. Aucune allocation mémoire pour la liste entière !



Comment cela fonctionne-t-il sous le capot ?



Le compilateur C# transforme la méthode avec yield en un véritable automate d'états (state machine). Il crée une classe qui implémente IEnumerable<T> et IEnumerator<T>. Cette classe stocke :

  • L'état courant (sur quelle ligne de la méthode nous nous sommes arrêtés).
  • Les variables locales de la méthode.
  • Une référence à l'objet courant (this), si la méthode n'est pas statique.


Chaque fois que MoveNext() est appelé (ce que fait foreach), l'automate d'états reprend l'exécution là où il s'était arrêté.



Exemple réel : lecture d'un gros fichier



Imaginez que vous devez traiter un fichier de logs de 10 Go. Si vous le lisez entièrement en mémoire, le programme plantera avec une OutOfMemoryException. Avec yield, vous pouvez lire le fichier ligne par ligne et traiter chaque ligne à la volée :



public static IEnumerable<s                

Blogs

Book Recommendations