Убегите некоторое время из цикла, который содержит оператор переключения

Я испытываю затруднения при выяснении, как убежать из цикла, который содержит оператор переключения. Повреждение убегает из переключателя, не цикла.

Существует, вероятно, более изящное решение этого. Я реализовал флаг, который начинается как верный и установлен на ложь и заканчивает цикл. Можно ли предложить лучшее решение?

Фон: этот код используется в системе организации технологических процессов штрихкода. У нас есть PocketPCs, которым встроили сканеры штрихкода. Этот код используется в одной из тех функций. Это предлагает пользователю различные части данных всюду по стандартной программе. Эта часть позволяет им просматривать путем прокрутки некоторые записи материально-технических ресурсов, отображающие ту информацию о терминале PocketPC (разбитые на страницы результаты), и позволяет им вводить "D" для Сделанного, "Q" для выхода.

Вот текущий пример C#, который должен быть улучшен:

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

Вот пример кода, который делает это в 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

Спасибо,

53
задан nawfal 14 October 2013 в 19:50
поделиться

11 ответов

Я нахожу эту форму еще более читабельной:

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; 
    } 
}
41
ответ дан 7 November 2019 в 08:20
поделиться

Вы можете изменить операцию переключения на петлю for/foreach. После выполнения условия установите "keepOnLooping" в false, а затем используйте break для выхода из цикла. Остальное должно позаботиться о себе.

.
0
ответ дан 7 November 2019 в 08:20
поделиться

IMO, это кажется совершенно прекрасным способом вырваться из петли , в то время как . Он делает то, что вы ожидаете, без побочных эффектов. Я мог бы подумать о том, чтобы сделать

if(!keepOnLooping)
  break;

, но это на самом деле не отличается с точки зрения исполнения.

.
1
ответ дан 7 November 2019 в 08:20
поделиться

Оберните его в функцию и используйте оператор возврата для выхода. Как насчет этого?

1
ответ дан 7 November 2019 в 08:20
поделиться

Вы можете заменить оператор switch на оператор if/else. Нет необходимости в goto и оператор break выходит из цикла:

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)
2
ответ дан 7 November 2019 в 08:20
поделиться

Флаг - это стандартный способ. Единственный известный мне способ - использовать goto.

4
ответ дан 7 November 2019 в 08:20
поделиться

Почему бы не обернуть переключатель в метод, который возвращает булева, чтобы продолжать петлевание? Это будет иметь дополнительное преимущество в том, что сделает код более читабельным. Есть причина, по которой кто-то написал статью о том, что нам все-таки не нужны goto statements ;)

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;
}
8
ответ дан 7 November 2019 в 08:20
поделиться

Для многоуровневых перерывов необходимо использовать оператор goto. Похоже, что это единственный "чистый" способ в C#. Использование флага также полезно, но требует дополнительного кода, если цикл имеет другие предикаты для выполнения.

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

Может быть интересно заметить, что некоторые другие неязыковые языки имеют многоуровневые перерывы, делая break levels; (Java также бесполезна, однако, как и использование goto, замаскированного под продолжение... :P)

.
10
ответ дан 7 November 2019 в 08:20
поделиться

Единственное, о чем я знаю, - это ужасное гото. MSDN также говорит об этом.

Однако, я не вижу причин, по которым вы бы использовали его в этом случае. То, как вы это реализовали, отлично работает и более удобно в обслуживании, чем goto. Я бы сохранил то, что у вас есть.

12
ответ дан 7 November 2019 в 08:20
поделиться

Одним из вариантов здесь является преобразование этого цикла в метод ("метод извлечения") и использование return.

30
ответ дан 7 November 2019 в 08:20
поделиться

Я бы попытался избежать этого, но вы могли бы использовать...

goto

Тем не менее, разгневанные толпы с вилками становятся профессиональной опасностью, если вы решите это сделать.

.
44
ответ дан 7 November 2019 в 08:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: