77 votes

Continuer dans les boucles imbriquées

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;
       }
   }
}
 

122voto

Eric Lippert Points 300275

Mise à JOUR: Cette question a été l'inspiration pour mon article sur ce sujet. Merci pour la grande question!


"continuer" et "pause" ne sont rien de plus qu'un agréable syntaxe pour un "goto". Apparemment, en leur donnant mignon noms et la restriction de leurs usages notamment les structures de contrôle, de ne plus attirer les foudres de la "toutes les gotos sont tous mauvais de tous les temps" de la foule.

Si ce que vous voulez faire est de continuer à l'extérieur, vous pourriez simplement définir une étiquette en haut de la boucle externe, puis "goto" de cette étiquette. Si vous estimé que cela n'a pas empêché la lisibilité du code, c'est peut-être le moyen le plus efficace de la solution.

Toutefois, je prendrais cela comme une occasion d'examiner si votre flux de contrôle gagnerait à refactoring. Chaque fois que j'ai conditionnelle "break" et "continue" dans les boucles imbriquées, je considère que le refactoring.

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, l'extrait de la boucle interne à une méthode:

foreach(var candidate in candidates)
{
  if (MeetsCriteria(candidate, criteria))
  { 
      successfulCandidate = candidate;
      break;
  }
}

Deuxièmement, pouvez toutes les boucles à être éliminé? Si vous êtes en boucle parce que vous essayez de chercher quelque chose, puis à refactoriser 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
}

Si il n'y a pas de boucles, puis il n'y a pas besoin de se casser ou continuent!

43voto

ryansstack Points 630
     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:
    }
 

Problème résolu. (quoi ?? Pourquoi me donnez-vous tous ce regard sale?)

22voto

Jake Pearson Points 9657

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é.

10voto

Welbog Points 32952

Échangez la structure try / catch avec la boucle while intérieure:

 while {
  try {
    while {
      throw;
    }
  }
  catch {
    continue;
  }
}
 

5voto

shahkalpesh Points 21553

Non.
Je suggère d'extraire 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;
       }
   }
}
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X