Question

Je ne parviens pas à trouver comment sortir d'une boucle qui contient une instruction switch. Briser les pauses de l'interrupteur, et non la boucle.

Il y a probablement une solution plus élégante à ce sujet. Je l'ai mis en place un drapeau qui commence comme vrai et obtient la valeur false et la boucle se termine. Pouvez-vous offrir une meilleure solution?

Arrière-plan: ce code est utilisé dans un système de workflow de codes à barres. Nous avons PocketPC qui ont des scanners de codes à barres intégrés. Ce code est utilisé dans l'une de ces fonctions. Il invite l'utilisateur à différentes données tout au long de la routine. Cette pièce leur permet de faire défiler des enregistrements d'inventaire indiquant que les informations sur le terminal PocketPC (paginés résultats) et leur permet d'entrer dans « D » pour DONE, « Q » pour quitter.

Voici l'exemple actuel de C # qui doit être amélioré:

do
{
    switch (MLTWatcherTCPIP.Get().ToUpper())
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "D": //DONE (exit out of this Do Loop)
            // break; // this breaks out of the switch, not the loop
            // return; // this exists entire method; not what I'm after
            keepOnLooping = false;
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (keepOnLooping);

Voici un exemple de code qui fait cela dans VB.NET

Do
    Select Case MLTWatcherTCPIP.Get().ToUpper
        Case "" ''#scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown()
        Case "P" ''#scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp()
        Case "D" ''#DONE (exit out of this Do Loop)
            Exit Do
        Case "Q" ''#QUIT (exit out to main menu)
            Return
    End Select
Loop

Merci,

Était-ce utile?

La solution

Je trouve cette forme d'être toujours aussi un peu plus lisible:

bool done = false;
while (!done) 
{ 
    switch (MLTWatcherTCPIP.Get().ToUpper()) 
    { 
        case "": //scroll/display next inventory location 
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); 
            break; 
        case "P": //scroll/display previous inventory location 
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown(); 
            break; 
        case "D": //DONE (exit out of this Do Loop) 
            done = true;
            break; 
        case "Q": //QUIT (exit out to main menu) 
            return; 
        default: 
            break; 
    } 
}

Autres conseils

Je vais essayer de l'éviter, mais vous pouvez utiliser ...

goto

Cependant, des foules en colère à coups de fourche devenir un risque professionnel si vous choisissez de le faire.

Une option ici est de factoriser cette boucle dans une méthode ( « méthode d'extraction ») et utiliser return.

La seule autre façon que je connaisse est le goto redoutée. MSDN dit aussi cela.

Cependant, je ne vois aucune raison pour laquelle vous souhaitez utiliser dans ce cas. La façon dont vous avez mis en œuvre fonctionne très bien, et est plus maintenable qu'un goto. Je garderais ce que vous avez.

Vous devez utiliser une instruction goto pour les pauses à plusieurs niveaux. Il semble être la seule façon « propre » en C #. L'utilisation d'un drapeau est également utile, mais nécessite un code supplémentaire si la boucle a d'autres situations difficiles pour la course.

http://msdn.microsoft.com/en -us / bibliothèque / aa664756 (VS.71) .aspx

Il peut être intéressant de noter que certaines autres langues non c ont des pauses multi-niveaux en faisant break levels; (Java est tout aussi inutile, cependant, car il utilise un goto déguisé en continue ..: P)

Pourquoi ne pas envelopper l'interrupteur dans une méthode qui retourne un booléen pour maintenir le bouclage? Il aurait l'avantage secondaire de rendre le code plus lisible. Il y a une raison que quelqu'un a écrit un article disant que nous ne avons pas besoin des déclarations goto après tout;)

do
{
    bool keepOnLooping = TryToKeepLooping();
} while (keepOnLooping);

private bool TryToKeepLooping()
{
    switch (MLTWatcherTCPIP.Get().ToUpper())
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "D": //DONE (exit out of this Do Loop)
            // break; // this breaks out of the switch, not the loop
            // return; // this exists entire method; not what I'm after
            return false;
        case "Q": //QUIT (exit out to main menu)
            return true;
        default:
            break;
    }

    return true;
}

Un drapeau est le moyen standard pour le faire. La seule autre façon que je connaisse est d'utiliser un goto.

Vous ne pouvez facilement sortir de la boucle extérieure, mais vous pouvez continue il.

Si vous inversez alors votre logique vous obtenez ceci. Notez qu'il est un break immédiatement après l'instruction de commutation pour sortir de la boucle.

Ce n'est pas un code très lisible à mon avis, et je pense que le drapeau est toujours préférable.

   do
         {
            switch (Console.ReadKey().KeyChar.ToString())
            {
                case "U":
                    Console.WriteLine("Scrolling up");
                    continue;

                case "J":
                    Console.WriteLine("Scrolling down");
                    continue;

                case "D": //DONE (exit out of this Do Loop)
                    break;

                case "Q": //QUIT (exit out to main menu)
                    return;

                default:
                    Console.WriteLine("Continuing");
                    continue;
            }

            break;

        } while (true);

        Console.WriteLine("Exited");

Vous pouvez remplacer l'instruction switch avec une déclaration if/else. Aucune goto nécessaire et l'instruction break quitte la boucle:

do
{
  String c = MLTWatcherTCPIP.Get().ToUpper();

  if (c = "")
    MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
  else if (c = "P")
    MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextUp();
  else if (c = "D")
     break;
  else if (c = "Q")
    return;
  else
  {
    // Handle bad input here.
  }
} while (keepLooping)

Enveloppez dans une fonction et utiliser une instruction de retour pour quitter. Que diriez-vous cela?

OMI, cela semble une façon parfaitement bien de sortir d'une boucle de while. Il fait ce que vous attendez sans effets secondaires. Je pouvais penser à faire

if(!keepOnLooping)
  break;

Mais ce n'est pas vraiment différent en termes d'exécution.

Ecrire quelque chose comme:

case "Exit/Break" :
                  //Task to do
                    if(true)
                      break;

Cette rupture ne sera pas associé à tous les cas. Il appartiendra à la boucle while.

Vous pouvez modifier l'instruction de passer à une boucle pour / foreach. Une fois que la condition est remplie set « keepOnLooping » false puis utilisez pause pour sortir de la boucle. Le reste devrait prendre soin de lui-même.

Une autre (pas grand) alternative consiste à gérer de façon unique le case où vous devez « sortir de la boucle » avec un if de suite et le déplacer hors du bloc de switch. Pas très élégant si l'interrupteur cas est très longue:

do
{
    var expression = MLTWatcherTCPIP.Get().ToUpper();
    if (expression = "D") //DONE (exit out of this Do Loop)
    {   
        statement;
        break;
    }

    switch (expression)
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (true); //or whatever your condition is

Vous pouvez également faire le case lui-même une partie de la condition de la boucle de while vous envisagez suffit de sortir de la boucle et le calcul de l'expression elle-même est trivial (comme la lecture d'une variable).

do
{
    switch (expression)
    {
        case "": //scroll/display next inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "P": //scroll/display previous inventory location
            MLTWatcherTCPIP.TerminalPrompt.ScrollBodyTextDown();
            break;
        case "Q": //QUIT (exit out to main menu)
            return;
        default:
            break;
    }
} while (condition && expression != "D");

Aussi, si refactoring la chose entière dans une nouvelle méthode (qui est la solution la plus élégante à ce) est inacceptable pour une raison quelconque, vous pouvez également compter sur un délégué anonyme pour faire la même chose dans la méthode existante.

ou non fonctionner, mais lamda pourquoi ne pas donner un coup de feu juste pour le fun

while(  (expr) => (){
switch(expr){
case 1: dosomething; return true; 
case 2 : something;return true;
case exitloop:return false;}
});   
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top