Dans cet exemple de code, existe-t-il un moyen de continuer sur la boucle externe à partir du bloc catch?
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
continue;
}
}
}
MISE À JOUR: Cette question a été une source d'inspiration pour mon article sur ce sujet. Merci pour la grande question!
"continue" et "break" ne sont rien d'autre qu'une syntaxe agréable pour un "goto". Apparemment, en leur donnant des noms mignons et en restreignant leurs usages à des structures de contrôle particulières, ils n'attirent plus la colère de la foule "tous les gotos sont tous mauvais tout le temps".
Si ce que vous voulez faire est une continuation vers l'extérieur, vous pourriez simplement définir une étiquette en haut de la boucle externe puis "goto" cette étiquette. Si vous estimiez que cela ne gênait pas la compréhensibilité du code, alors cela pourrait être la solution la plus opportune.
Cependant, je saisirais cela comme une opportunité pour examiner si votre flux de contrôle bénéficierait d'une refactorisation. Chaque fois que j'ai une "pause" conditionnelle et une "poursuite" dans les boucles imbriquées, je pense à une refactorisation.
Considérer:
successfulCandidate = null;
foreach(var candidate in candidates)
{
foreach(var criterion in criteria)
{
if (!candidate.Meets(criterion)) // Edited.
{ // TODO: no point in continuing checking criteria.
// TODO: Somehow "continue" outer loop to check next candidate
}
}
successfulCandidate = candidate;
break;
}
if (successfulCandidate != null) // do something
Deux techniques de refactoring:
Tout d'abord, extrayez la boucle interne d'une méthode:
foreach(var candidate in candidates)
{
if (MeetsCriteria(candidate, criteria))
{
successfulCandidate = candidate;
break;
}
}
Deuxièmement, toutes les boucles peuvent-elles être éliminées? Si vous effectuez une boucle parce que vous essayez de rechercher quelque chose, refactorisez-le dans une requête.
var results = from candidate in candidates
where criteria.All(criterion=>candidate.Meets(criterion))
select candidate;
var successfulCandidate = results.FirstOrDefault();
if (successfulCandidate != null)
{
do something with the candidate
}
S'il n'y a pas de boucles, il n'est pas nécessaire de rompre ou de continuer!
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
goto REPEAT;
}
}
// end of outer loop
REPEAT:
// some statement or ;
}
Problème résolu. (quoi ?? Pourquoi me donnez-vous tous ce regard sale?)
Vous pouvez utiliser une pause; déclaration.
while
{
while
{
try
{
throw;
}
catch
{
break;
}
}
}
Continuer est utilisé pour revenir en haut de la boucle actuelle.
Si vous avez besoin de sortir plus de niveaux que cela, vous devrez soit ajouter une sorte de "si" ou utiliser le "goto" redouté/non recommandé.
Échangez la structure try/catch avec la boucle while intérieure:
while {
try {
while {
throw;
}
}
catch {
continue;
}
}
Non.
Je suggère, en extrayant la boucle intérieure dans une méthode distincte.
while
{
// outer loop
try
{
myMethodWithWhileLoopThatThrowsException()
}
catch
{
// how do I continue on the outer loop from here?
continue;
}
}
}
Utilisez break
dans la boucle interne.
Vous voulez juste rompre avec l'intérieur qui continuerait avec l'extérieur.
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// how do I continue on the outer loop from here?
break;
}
}
}
using System;
namespace Examples
{
public class Continue : Exception { }
public class Break : Exception { }
public class NestedLoop
{
static public void ContinueOnParentLoopLevel()
{
while(true)
try {
// outer loop
while(true)
{
// inner loop
try
{
throw new Exception("Bali mu mamata");
}
catch (Exception)
{
// how do I continue on the outer loop from here?
throw new Continue();
}
}
} catch (Continue) {
continue;
}
}
}
}
}
Je pense que la meilleure façon d'y parvenir serait d'utiliser l'instruction break. Break termine la boucle en cours et continue l'exécution de l'endroit où elle se termine. Dans ce cas, il faudrait terminer la boucle interne et revenir dans la boucle while externe. Voici à quoi ressemblerait votre code:
while
{
// outer loop
while
{
// inner loop
try
{
throw;
}
catch
{
// break jumps to outer loop, ends inner loop immediately.
break; //THIS IS THE BREAK
}
}
}
Je crois que c'est ce que vous cherchiez à accomplir, n'est-ce pas? Merci!