Хотя это решение не элегантно, и многие люди скажут вам, что оно подвергает вас всевозможным опасностям, вы всегда можете просто сделать:
Restart:
foreach(var item in things)
{
DoSomething(item);
if(WeShouldStartOver()) goto Restart;
}
Это легко, понятно и правильно. (Многие люди рефлексивно скажут вам, что gotos являются порождением зла и всегда неправы. Эти люди могут путать «неэгоистичную» и «легко злоупотребляемую» с «морально неправильной».)
Если вы один из тех людей, которые думают, что goto всегда неправы, вы можете скрыть goto. Таинственным образом, когда вы произносите «goto» как «while» и «break», это больше не является морально неправильным!
bool loopTheLoop = true;
while(loopTheLoop)
{
loopTheLoop = false;
foreach(var item in things)
{
DoSomething(item);
if(WeShouldStartOver())
{
loopTheLoop = true;
break;
}
}
}
Это намного дольше, имеет гораздо более сложный поток управления и использует флаг данных только для потока управления, а не для выражения значения в бизнес-сфере программы. Я бы сказал, что все эти вещи такие же плохие, как «goto», но некоторым людям действительно нравятся такие вещи.
Лично я был бы склонен преобразовать цикл в вспомогательный метод:
while(LoopTheLoop()) {}
...
// Returns true if we bailed early, false if we did not.
bool LoopTheLoop()
{
foreach(var item in things)
{
DoSomething(item);
if(WeShouldStartOver()) return true;
}
return false;
}
Можете ли вы объяснить почему вы хотите сделать эту странную вещь? Может быть, есть лучший способ сделать то, что вы хотите. Потому что, честно говоря, все эти решения довольно плохие.