
Le mot-clé yield en C# est un outil puissant permettant d’optimiser la gestion de la mémoire et d’améliorer les performances des itérations. Bien que souvent sous-utilisé, il peut être un atout majeur pour les développeurs cherchant à optimiser leurs algorithmes. Dans cet article, nous allons explorer son fonctionnement, ses avantages et des exemples concrets d’utilisation.
Introduction
Ce mot-clé permet de créer des itérateurs paresseux (lazy iterators). Contrairement à une méthode classique qui retourne une liste entière, une méthode utilisant yield génère les valeurs à la demande, évitant ainsi la surcharge mémoire.
Comparaison : Avec et Sans yield
Voyons une comparaison entre un code qui utilise yield et un autre qui ne l’utilise pas.
Sans yield
IEnumerable<int> MethodeSansYield()
{
var list = new List<int>();
for (int i = 0; i < 5; i++)
{
list.Add(i);
}
return list;
}
foreach (var number in MethodeSansYield())
{
Console.WriteLine(number);
}
Le problème de cette approche est qu’on stocke toute la liste en mémoire avant même son utilisation.
Avec yield
IEnumerable<int> MethodeAvecYield()
{
for (int i = 0; i < 5; i++)
{
yield return i;
}
}
foreach (var number in MethodeAvecYield())
{
Console.WriteLine(number);
}
A chaque itération du foreach, yield produit une valeur. Les valeurs sont générées et consommées au fur et à mesure, sans créer une liste intermédiaire.
yield return 0 -> Console.WriteLine(0)
yield return 1 -> Console.WriteLine(1)
yield return 2 -> Console.WriteLine(2)
yield return 3 -> Console.WriteLine(3)
yield return 4 -> Console.WriteLine(4)
Certains pourraient se dire, où est le drame si on stocke toutes les valeurs dans une table intermédiaire? Lorsque la table ne contient qu’une dizaine de valeurs ce n’est pas grave. Mais si elle en contient des millions ça change tout. Prenons un exemple plus parlant.
Quand utiliser yield ?
Prenons un autre exemple qui montre sa puissance
IEnumerable<int> MethodeSansYieldOptimisee()
{
var list = new List<int>();
for (int i = 0; i < int.MaxValue; i++)
{
list.Add(i);
}
return list;
}
foreach (var number in MethodeSansYieldOptimisee().Take(10))
{
Console.WriteLine(number);
}
Dans le code ci-dessus, je veux récupérer les 10 premières valeurs de mon tableau qui en contient plus de 2 milliards. Sans yield, je suis obligé de charger toutes les valeurs pour récupérer les 10 premières.
Stocker ces 2 147 483 647 valeurs est catastrophique en terme d’utilisation de mémoire (risque de System.OutOfMemoryException) et de temps d’exécution. Tout ça pour récupérer 10 valeurs.
Voyons ce que ça donne avec yield:
IEnumerable<int> MethodeAvecYieldOptimisee()
{
for (int i = 0; i < int.MaxValue; i++)
{
yield return i;
}
}
foreach (var number in MethodeAvecYieldOptimisee().Take(10))
{
Console.WriteLine(number);
}
Cette fois, pas besoin de charger toutes les valeurs du tableau. On récupère les valeurs du tableau au fur et à mesure qu’on le parcourt. L’exécution ne prend que quelques secondes et ne consomme pas la mémoire de manière excessive.

Conclusion
L’utilisation de yield est particulièrement avantageuse lorsque:
- Les données sont volumineuses et ne tiennent pas en mémoire.
- On veut éviter de calculer inutilement des valeurs qui ne seront pas utilisées.
- On veut améliorer la performance d’itérations progressives.
Bien que non indispensable, il peut être un excellent outil pour optimiser la gestion des données en C#.
nlnyd9