C # - цикл foreach внутри цикла while - выйти из цикла foreach и сразу продолжить цикл while?

while (foo() == true)
{
   foreach (var x in xs)
   {
       if (bar(x) == true)
       {
           //"break;" out of this foreach
           //AND "continue;" on the while loop.
       }
   }

   //If I didn't continue, do other stuff.
}

Я немного не понимаю, как это сделать.


Обновление: я исправил вопрос. Я упустил тот факт, что мне нужно обрабатывать другие вещи, если я не вызываю continue; в цикле while.

Извините, я не понял, что употребил слово «что-то» дважды.


person myermian    schedule 15.07.2011    source источник
comment
просто break; пока будет продолжаться, потому что something is true   -  person Djole    schedule 15.07.2011
comment
Извините, я кое-что упустил. Мне нужно иметь возможность обрабатывать дополнительные элементы, если я не continue;.   -  person myermian    schedule 15.07.2011
comment
тогда вам нужно либо написать if(something)continue; при выходе из цикла foreach, либо использовать goto label   -  person Djole    schedule 15.07.2011
comment
Затем отредактируйте вопрос, чтобы он был понятен! Этот вопрос очень непонятный. Вы используете что-то для обозначения двух разных вещей, очень неясно, где в этих циклах находятся необходимые побочные эффекты и так далее. Возможно, удастся полностью переписать все это без циклов, или преобразовать его в методы, или что-то еще, но, не зная, в чем заключается настоящая проблема, трудно сказать.   -  person Eric Lippert    schedule 15.07.2011
comment
Ой, ой. Я даже не осознавал, что использовал что-то дважды.   -  person myermian    schedule 15.07.2011
comment
foo и bar используются только для своих значений, или они также имеют побочный эффект?   -  person Eric Lippert    schedule 15.07.2011
comment
@Eric: Думаю, мне действительно не стоит упрощать это, не так ли? Да ладно, кто-то понял, что мне нужно, и ответил на это.   -  person myermian    schedule 15.07.2011
comment
@Eric: Мой предыдущий комментарий означал, что я не должен всегда пытаться упростить вопрос, b / c на этот раз я использовал одно и то же слово для разных значений и упустил важную часть вопроса.   -  person myermian    schedule 15.07.2011


Ответы (6)


Если я правильно вас понял, вы можете использовать LINQ Any / здесь предикат All:

while (something)
{
    // You can also write this with the Enumerable.All method
   if(!xs.Any(x => somePredicate(x))
   {
      // Place code meant for the "If I didn't continue, do other stuff."
      // block here.
   }
}
person Ani    schedule 15.07.2011

Я бы переписал это:

while (foo() == true)
{
   foreach (var x in xs)
   {
       if (bar(x) == true)
       {
           //"break;" out of this foreach
           //AND "continue;" on the while loop.
       }
   }

   //If I didn't continue, do other stuff.
   DoStuff();
}

as

while (foo()) // eliminate redundant comparison to "true".
{
   // Eliminate unnecessary loop; the loop is just 
   // for checking to see if any member of xs matches predicate bar, so
   // just see if any member of xs matches predicate bar!
   if (!xs.Any(bar))        
   {
       DoStuff();
   }
}
person Eric Lippert    schedule 15.07.2011
comment
Это лучше, чем то, что я пытался сделать. :) - person myermian; 15.07.2011
comment
@myermian: Хорошее практическое правило, которое я пытаюсь использовать: если цикл предназначен для многократного выполнения определенного побочного эффекта, тогда используйте цикл. Если цикл предназначен исключительно для вычисления значения, тогда переместите цикл во вспомогательную функцию или найдите вспомогательную функцию, которая уже делает то, что вы хотите - например, Any, или All, или Sum, или что-то еще. . Таким образом, вы делаете цикл деталью реализации помощника, а не вложенным потоком управления вашего метода. - person Eric Lippert; 15.07.2011
comment
Да, я даже не думал о функциях «Все» или «Все». Но в конечном итоге это очень помогло. Я перевернул if, он continues, если он соответствует любому, и выполняет DoStuff () в противном случае (Resharper согласился, что инверсия if помогает избежать вложенности). Это намного чище, чем наличие значения bool, его установка, выход из цикла for, проверка bool, чтобы увидеть, какой был результат ... - person myermian; 15.07.2011
comment
@myermian / eric: Из любопытства, чем это отличается от моего ответа? - person Ani; 16.07.2011

Это должно соответствовать вашим требованиям:

while (something)
{   
    bool doContinue = false;

    foreach (var x in xs)   
    {       
        if (something is true)       
        {           
            //Break out of this foreach           
            //AND "continue;" on the while loop.          
            doContinue = true; 
            break;       
        }   
    }

    if (doContinue)
        continue;

    // Additional items.
}

Такой код часто встречается, когда вам нужно break распространяться через вложенные конструкции. Является ли это запахом кода или нет, остается предметом обсуждения :-)

person Adam Houldsworth    schedule 15.07.2011

while (something)
{
   foreach (var x in xs)
   {
       if (something is true)
       {
           break;
       }
   }
}

однако разве оба этих значения не всегда равняются истине ???

person FiveTools    schedule 15.07.2011

Итак, вы хотите продолжить после взлома?

while (something)
{
    bool hit = false;

    foreach (var x in xs)
    {
        if (something is true)
        {
            hit = true;
            break;
        }
    }

    if(hit)
        continue;
}
person Lourens    schedule 15.07.2011

person    schedule
comment
Извините, я кое-что упустил. Мне нужно иметь возможность обрабатывать дополнительные элементы, если я не continue;. - person myermian; 15.07.2011
comment
Пахнет необходимым рефакторингом - я думаю, вам нужно взглянуть на условную логику, которую вы используете ... - person FiveTools; 15.07.2011
comment
извините, я не понял ваш комментарий или обновление - вы хотите остаться на некоторое время после перерыва? - person adrianos; 15.07.2011
comment
Да, я напортачил, употребив этот термин дважды. - person myermian; 15.07.2011
comment
но нажатие на разрыв цикла for продолжит цикл while - person adrianos; 15.07.2011