break termine une boucle plus tôt. continue saute le reste de l'itération en cours et passe à la suivante. Les deux s'appliquent à la boucle englobante la plus interne, et fonctionnent de la même façon dans for, foreach, while et do while.
Sortie :
process order of 45
skip invalid total 0
process order of 120
skip invalid total -5
process order of 80
test order found, stopping
after the loop
continue a sauté la ligne de traitement pour 0 et -5. break a arrêté la boucle à 999, donc 60 n'a jamais été visité, et l'exécution a repris à la première instruction après la boucle.
break : s'arrêter quand la réponse est connue
L'usage typique de break est une recherche : une fois que vous avez trouvé ce que vous cherchiez, il n'y a aucune raison d'examiner le reste.
Sortie :
first invalid email at index 1
L'itérateur (i++) ne s'exécute pas après un break, donc i contiendrait encore l'index trouvé s'il était déclaré en dehors de la boucle. Pour les recherches simples, un appel de bibliothèque dit la même chose : Array.FindIndex(emails, e => !e.Contains("@")) renvoie l'index (ou -1), et le emails.Any(e => !e.Contains("@")) de LINQ indique s'il en existe un invalide.
continue : passer à l'itération suivante
continue est une clause de garde pour les boucles. Au lieu d'envelopper le vrai travail dans un if, rejetez en haut les cas dont vous ne voulez pas :
Sortie :
pen costs 1.20
mug costs 8.00
L'endroit où continue mène dépend de la boucle. Dans une boucle for, il exécute l'itérateur puis teste la condition. Dans une boucle while, il saute directement à la condition, ce qui mène à un bug classique :
int i = 0;
while (i < 10)
{
if (i % 2 == 0)
continue; // i++ below is skipped: i stays 0 forever
Console.WriteLine(i);
i++;
}
Mettez à jour le compteur avant tout continue, ou utilisez une boucle for, où la mise à jour se trouve dans l'en-tête et s'exécute toujours.
break dans un switch dans une boucle
Dans un switch, break termine la section du case. Quand ce switch se trouve dans une boucle, le break appartient au switch, pas à la boucle :
Sortie :
quit received
count = 2
Un simple break dans le cas "quit" n'aurait terminé que le switch, la boucle aurait continué, et count vaudrait 3. Le goto saute à l'étiquette placée après la boucle. Déplacer la boucle dans une méthode et écrire return dans ce cas fonctionne aussi et ne demande pas d'étiquette.
Sortir de boucles imbriquées
C# n'a pas de break étiqueté comme le break outer; de Java. Quand une recherche parcourt deux boucles imbriquées, un break dans la boucle interne ne termine que celle-ci ; la boucle externe passe à sa ligne suivante. Il existe trois corrections standard.
1. Un indicateur que la boucle externe vérifie :
Sortie :
first free seat: row 1, seat 2
2. goto vers une étiquette après les deux boucles. C'est le seul endroit où beaucoup de guides de style C# acceptent goto, car il exprime exactement « quitter les deux boucles » :
for (int row = 0; row < rows; row++)
{
for (int col = 0; col < cols; col++)
{
if (seats[row, col] == 0)
{
Console.WriteLine($"first free seat: row {row}, seat {col}");
goto done;
}
}
}
done:
Console.WriteLine("search finished");
3. Une méthode avec return, en général la solution la plus propre, car la recherche reçoit un nom et peut renvoyer son résultat :
Sortie :
first free seat: row 1, seat 2
C# 7.0 a aussi introduit les fonctions locales, qui permettent de placer cette méthode auxiliaire à l'intérieur de la méthode appelante. Le schéma avec paramètres out utilisé ici est expliqué sur la page ref et out.
goto et les étiquettes
Une étiquette est un identifiant suivi de deux-points, et goto label; y saute. Les règles sont assez strictes pour empêcher les pires abus :
- L'étiquette doit se trouver dans la même méthode, dans le même bloc que le
gotoou dans un bloc englobant. Vous pouvez sauter hors d'un bloc mais jamais dans un bloc : sauter depuis l'extérieur vers une étiquette située dans le corps d'une boucle donne l'erreur CS0159 (no such label within the scope of the goto statement). - Vous ne pouvez pas quitter un bloc
finallyavecgoto,breakoucontinue. - Dans un
switch,goto case 3;etgoto default;transfèrent le contrôle vers une autre section. C'est ainsi qu'un switch C# exprime l'enchaînement des cas, puisque glisser implicitement dans le cas suivant est une erreur de compilation.
goto permet aussi de construire des boucles (en sautant en arrière vers une étiquette), mais une boucle while dit la même chose sous une forme que tout lecteur reconnaît. Réservez goto à la sortie de boucles imbriquées et aux sections de switch.
return, throw et les boucles
return quitte toute la méthode, donc aussi toutes les boucles qu'elle contient. throw fait de même en levant une exception. Dans un bloc try doté d'un finally, break, continue, goto et return exécutent tous le bloc finally avant que le contrôle ne passe ailleurs, ce qui permet de sortir sans risque d'une boucle qui garde un fichier ouvert dans un bloc using.
| Instruction | Quitte | Reprend à |
|---|---|---|
continue | l'itération en cours | l'itération suivante (itérateur, puis condition) |
break | la boucle ou le switch le plus interne | l'instruction qui suit |
goto label | tous les blocs englobants | l'étiquette |
return | la méthode | l'appelant |
throw | tout jusqu'au catch correspondant | le bloc catch |
Questions fréquentes
Quelle est la différence entre break et continue en C# ?
break termine immédiatement la boucle (ou le switch) la plus interne ; l'exécution reprend après elle. continue ne termine que l'itération en cours et passe à la suivante : dans une boucle for, l'itérateur s'exécute ensuite, dans while et do while la condition est testée ensuite, dans foreach l'élément suivant est récupéré.
Comment sortir de boucles imbriquées en C# ?
C# n'a pas de break étiqueté. Les trois options sont : positionner un indicateur bool et le tester dans la boucle externe, sauter après les deux boucles avec goto vers une étiquette, ou déplacer les boucles dans une méthode et en sortir avec return. La version méthode est en général la plus propre, car elle donne aussi à la recherche un nom et une valeur de retour.
break dans un switch quitte-t-il la boucle en C# ?
Non. Dans un switch placé dans une boucle, break termine la section du switch et la boucle continue. Pour quitter la boucle depuis un case, utilisez return, un indicateur testé après le switch, ou goto vers une étiquette après la boucle. continue dans un case passe bien à l'itération suivante de la boucle.
goto est-il autorisé en C# ?
Oui. goto label; saute à label: dans la même méthode, mais il ne peut pas sauter à l'intérieur d'un bloc ni sortir d'un finally. Dans un switch, goto case value; et goto default; sautent d'une section à l'autre. En dehors de la sortie de boucles imbriquées et de l'enchaînement explicite des cas d'un switch, goto est rarement le choix le plus clair.