Parlons de la maîtrise des boucles foreach en C# et de l'amélioration de l'efficacité de votre programmation ! Les boucles Foreach sont un concept important dans la programmation C# – et dans de nombreux autres langages d’ailleurs. Lorsqu'il s'agit de parcourir des collections et des tableaux, ils sont particulièrement utiles.
À la fin de cet article, vous pouvez vous attendre à avoir une solide compréhension de la syntaxe de base des boucles foreach, des erreurs courantes à éviter, des techniques avancées à essayer et des meilleures pratiques pour les utiliser efficacement dans vos propres projets.
Que vous soyez débutant ou ingénieur logiciel expérimenté, cet article vous fournira des informations précieuses sur la façon d'utiliser les boucles foreach pour rationaliser votre code et améliorer vos compétences en programmation.
Les boucles Foreach sont essentielles pour les ingénieurs logiciels et les développeurs qui travaillent avec des collections et des tableaux en C#. Ils permettent l'itération de ces structures de données avec une syntaxe simple et concise qui rend leur utilisation plus facile et plus efficace. L'un des principaux avantages de l'utilisation des boucles foreach est qu'elles sont moins complexes que les boucles for traditionnelles. Dites adieu à la vérification et à l'indexation des plages !
Les boucles For nécessitent l'utilisation d'une variable d'index, ce qui nécessite souvent des déclarations et des affectations supplémentaires. D'un autre côté, les boucles foreach gèrent la variable d'index et la logique d'itération en coulisse, réduisant ainsi la quantité de code nécessaire pour parcourir une collection ou un tableau. Cette simplicité conduit à un code plus propre, plus facile à lire et à maintenir.
Un autre avantage de l’utilisation des boucles foreach est un débogage plus facile. Étant donné que la logique itérative est abstraite, les erreurs de codage qui se produisent au cours du processus itératif sont plus faciles à diagnostiquer. Ceci est particulièrement pertinent lors de l'utilisation de boucles for où il existe un risque d'erreur ponctuelle qui peut être difficile à identifier et à résoudre.
La syntaxe de base d'une boucle foreach en C# est la suivante :
dataType[] collectionName = new dataType[10]; foreach (dataType variableName in collectionName) { //Execute code for each item in collectionName using variableName as you go. }
Le dataType est le type des éléments de la collection, variableName est le nom attribué à l'élément actuel de la collection lors de son itération et collectionName est le nom de la collection itérée. Le mot-clé 'in' indique à C# que la boucle est une boucle foreach et que la logique à l'intérieur des accolades est exécutée pour chaque élément de la collection.
Les boucles Foreach peuvent également être utilisées conjointement avec l'interface IEnumerable, qui permet d'accéder aux valeurs d'une collection une par une. L'utilisation de l'interface IEnumerable et des boucles foreach peut réduire l'utilisation de la mémoire et augmenter les performances en permettant aux développeurs d'obtenir les valeurs de la collection uniquement lorsque cela est nécessaire - mais ce n'est pas toujours aussi noir et blanc .
Cette approche est couramment utilisée lorsqu’il s’agit de grands ensembles de données qu’il serait difficile de traiter en une seule fois.
Lors de l'utilisation de boucles foreach, les développeurs peuvent rencontrer plusieurs erreurs courantes s'ils ne font pas attention. Il est important de veiller à éviter ces erreurs car elles peuvent entraîner des bogues, des plantages et des erreurs d’exécution difficiles à résoudre. Certaines des erreurs les plus courantes sont abordées ci-dessous avec des conseils sur la façon de les éviter et de les résoudre.
Une erreur consiste à tenter de modifier la collection itérée pendant la boucle. Les collections modifiées peuvent provoquer un comportement inattendu, tel qu'une boucle infinie ou le saut de certains éléments. Pour éviter cette erreur, il est important de créer une copie de la collection avec laquelle travailler si une modification est nécessaire, supprimant ainsi le risque de modification directe de la collection originale au cours du processus d'itération.
Une autre erreur courante consiste à ne pas vérifier les références nulles avant de tenter une itération. Cette erreur peut conduire à des exceptions de référence nulle, ce qui peut provoquer le blocage du programme et être difficile à détecter et à résoudre. Vérifier les références nulles avant de démarrer le processus d'itération est un moyen efficace d'éviter cette erreur.
Les problèmes de modifications simultanées peuvent également être frustrants, provoquant un comportement imprévisible du programme et des défauts difficiles à reproduire. Cela peut se produire si plusieurs threads accèdent et modifient la même collection. Les développeurs peuvent éviter les problèmes de modification simultanée en utilisant une classe de collection synchronisée ou en utilisant des verrous pour garantir qu'un seul thread peut modifier la collection à la fois.
Une instruction break terminera immédiatement la boucle une fois exécutée, que la collection ait fini d'itérer ou non. Alternativement, une instruction continue passera immédiatement à l'itération suivante de la boucle, en sautant les lignes de code restantes dans l'itération en cours. Ces instructions peuvent être utilisées pour simplifier la vérification des erreurs et améliorer la lisibilité du code.
Par exemple, une instruction break peut être utile lors de la recherche d'un élément spécifique dans une collection, et la boucle peut être arrêtée dès que l'élément est trouvé. Lorsqu'elles sont utilisées correctement, les instructions break et continue peuvent réduire la complexité du code, augmenter ses performances et le rendre plus facile à suivre et à comprendre.
Consultez ce code pour un exemple du mot-clé break.
Item? foundItem = null; foreach (var item in collection) { if (item.Name == "Dev Leader") { foundItem = item; break; } }
À mesure que vous serez plus à l’aise avec l’utilisation des boucles foreach en C#, ils voudront peut-être explorer certaines des techniques avancées dont ils disposent. Les techniques avancées avec les boucles foreach peuvent aider à optimiser davantage le code et à améliorer les performances. Cette section explorera plusieurs techniques à un niveau élevé, notamment les requêtes et lambdas LINQ, l'énumération et le filtrage, ainsi que la parallélisation.
Chacun de ces sujets mérite son propre article complet.
Une technique avancée consiste à utiliser des requêtes LINQ et des lambdas avec des boucles foreach. LINQ permet aux développeurs d'écrire du code plus concis et expressif. Les requêtes peuvent être écrites à l'aide de la syntaxe LINQ et les lambdas peuvent être utilisés pour filtrer, trier et manipuler les données directement dans la boucle, réduisant ainsi le besoin de boucles ultérieures.
Voyons un exemple :
public sealed record Item( int Id, string Name, DateTime CreatedDateTimeUtc); // Use .Select() from LINQ to change what we're operating on foreach (var item in collection.Select(x => new { Id = x.Id, Name = x.Name })) { if (item.Name == "Dev Leader") { // we're only interested in the ID, so return it! return item.Id; } }
Une autre technique est l’énumération et le filtrage, qui peuvent contribuer à réduire l’empreinte mémoire des grands ensembles de données. Cette technique permet de générer uniquement le sous-ensemble de données pertinent pour l'opération en cours et qui répond à un critère spécifique. Cela peut s’avérer très utile lorsqu’il s’agit de grands ensembles de données, car cela évite d’avoir à traiter l’intégralité de l’ensemble de données en même temps, ce qui peut prendre du temps et entraîner des problèmes de performances.
Regardons un exemple de code :
public sealed record Item( int Id, string Name, DateTime CreatedDateTimeUtc); // Put the filtering right in the foreach line by using .Where() from LINQ foreach (var item in collection.Where(x => x.Name == "Dev Leader")) { // we're only interested in the ID, so return it! return item.Id; }
La parallélisation est une autre technique avancée qui peut être utilisée avec les boucles foreach. La parallélisation d'une boucle foreach peut être un moyen de tirer parti des processeurs multicœurs et d'améliorer les performances. La parallélisation peut être obtenue grâce à l'utilisation de l'opérateur LINQ parallèle, PLINQ, qui peut diviser le processus d'itération en morceaux plus petits et les exécuter sur des threads séparés.
Nous pouvons également utiliser des éléments comme Parallel.Foreach
, Parallel.ForeachAsync
, et même diviser le travail en tâches dédiées et attendre les résultats à l'aide de Task.WhenAll()
. Vous pourriez être intéressé à regarder cette vidéo pour découvrir certaines différences de performances lorsque vous examinez ces options !
LINQ, ou Language Integrated Query, est une fonctionnalité de langage puissante en C# qui permet aux développeurs d'interagir avec diverses sources de données de manière plus expressive et efficace. La possibilité d'utiliser des requêtes LINQ conjointement avec des boucles foreach peut simplifier le code et réduire la complexité, rendant le code plus lisible et maintenable.
Pour utiliser LINQ avec des boucles foreach, la requête est exécutée en dehors de la boucle et enregistrée dans une variable. La variable de requête est ensuite itérée à l'aide de la boucle foreach. Les requêtes LINQ courantes incluent OrderBy
, qui trie les données par ordre croissant ou décroissant, et Where()
, qui renvoie un sous-ensemble d'éléments répondant à un critère spécifique. L'écriture de requêtes LINQ personnalisées peut être effectuée à l'aide d'expressions lambda, permettant ainsi aux développeurs de manipuler les données de manière significative.
Lorsque vous travaillez avec des boucles foreach en C#, il existe plusieurs bonnes pratiques à garder à l'esprit. En suivant ces pratiques, les développeurs peuvent garantir que leur code est efficace et maintenable, exempt d'erreurs et conforme aux normes de l'industrie. Certaines des meilleures pratiques les plus importantes sont décrites ci-dessous.
Choisir le type de données approprié à parcourir est une bonne pratique importante pour travailler avec des boucles foreach. Certains types de données, tels que les listes et les tableaux, sont plus adaptés aux boucles foreach, tandis que d'autres, comme les tables de hachage, peuvent ne pas être aussi efficaces. Il est important de prendre en compte à la fois la structure des données et le type de données stockées lors de la sélection du type de données approprié à parcourir.
Dans les versions plus récentes de dotnet (au moment de la rédaction !), des gains de performances incroyables ont été réalisés pour les tableaux et les listes. Historiquement, une boucle foreach n'était peut-être pas aussi performante qu'une boucle for avec un indexeur. Cependant, l’équipe dotnet a fait de la magie ! Je vous recommande fortement de regarder cette vidéo pour quelques détails sur les performances :
Utiliser des collections en lecture seule dans la mesure du possible est une autre bonne pratique importante lorsque vous travaillez avec des boucles foreach. Les collections en lecture seule peuvent aider à empêcher la modification de la structure des données pendant le processus d'itération, réduisant ainsi le risque d'erreurs. Si une modification est nécessaire, il est préférable de faire une copie de la collection et de travailler avec la copie plutôt que de modifier l'original.
Combattre les problèmes où une collection a été modifiée pendant le dénombrement est un véritable casse-tête.
Garder le code simple et éviter toute complexité inutile est une autre bonne pratique qui peut permettre de gagner du temps et de réduire les erreurs. Le code doit rester propre et lisible, avec une structure claire et logique facile à suivre. Ceci peut être réalisé en utilisant des noms de variables descriptifs et en regroupant le code en fonctions et classes.
J'ai constaté qu'en tant que programmeurs, nous avons tendance à nous appuyer sur certaines des options LINQ dont nous disposons. Le résultat est parfois que nous avons ces requêtes LINQ enchaînées et compliquées qui font des choses géniales mais… elles sont difficiles à lire. Gardez cela à l’esprit lorsque vous essayez de filtrer et de manipuler des données.
Éviter les optimisations prématurées est un autre aspect important du travail avec les boucles foreach. Les développeurs doivent éviter d’optimiser le code avant d’avoir une compréhension claire de ce qui doit être optimisé. Optimiser le code trop tôt peut entraîner un manque de clarté et provoquer des bugs de régression.
Vous vous souvenez des points sur le parallélisme plus haut dans l'article ? Si vous débutez… ne perdez pas encore votre temps avec ce genre de choses. Obtenez les bases. Obtenez des bases solides avant de passer aux aspects plus avancés.
L'utilisation de noms de variables concis et descriptifs est une autre bonne pratique importante lorsque vous travaillez avec des boucles foreach. Les noms de variables doivent être courts et descriptifs et doivent refléter l'objectif de la variable. Cela peut contribuer à améliorer la lisibilité du code et à le rendre plus facile à comprendre.
Cette astuce est-elle spécifique aux boucles foreach ? Absolument pas. Mais c'est tellement important en programmation que je continuerai à trouver des moyens de l'introduire pour rappeler aux gens l'importance d'un code lisible.
Une vérification appropriée des erreurs et une gestion des exceptions sont des bonnes pratiques cruciales lorsque vous travaillez avec des boucles foreach. La vérification des erreurs doit être incluse dans tout le code, en particulier lorsque vous travaillez avec des collections et des tableaux. Toutes les exceptions levées au cours du processus d'itération doivent être gérées correctement à l'aide des instructions try-catch. Cela peut aider à éviter les plantages du programme et à améliorer la maintenabilité du code.
Comprendre les boucles foreach en C# est une compétence fondamentale pour les développeurs. En utilisant les boucles foreach, vous pouvez gagner du temps, écrire un code plus propre et plus concis et éviter les pièges courants associés aux boucles for traditionnelles. Tout au long de cet article, j'ai couvert la syntaxe de base des boucles foreach en C#, les erreurs courantes à éviter, les techniques avancées telles que les requêtes LINQ et les lambdas, et les meilleures pratiques d'utilisation des boucles foreach.
N'oubliez pas de toujours choisir le type de données approprié sur lequel parcourir, d'utiliser des collections en lecture seule autant que possible et de garder votre code simple et concis. Avec de la pratique et de l'application, vous pouvez améliorer votre écriture de l'un des outils les plus utilisés en C#.
J'espère que vous avez trouvé quelque chose d'utile dans cet article ! Si vous êtes intéressé par plus d'opportunités d'apprentissage, abonnez-vous à ma newsletter hebdomadaire gratuite et !
Également publié ici