Перезапустить цикл foreach в C#?
как я могу перезапустить foreach
цикл в C#??
например:
Action a;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart;
}
}
restart
вот так continue
или break
но он перезапускает foreach с самого начала
Это похоже на установку счетчика for
цикл до 0 снова..
это возможно в C#?
Edit: я хочу поблагодарить как Mehrdad Afshari, так и Mahesh Velaga за то, что позволили мне обнаружить ошибку (index=0) в моей текущей реализации, которая не была бы обнаружена иначе..
5 ответов
использовать старый добрый goto
:
restart:
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
goto restart;
}
}
Если вы диагностированы с gotophobia 100% времени по какой-либо причине (что не хорошо, что без причины), вы можете попробовать использовать флаг:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
один из способов сделать это-использовать for, как вы уже упоминали:
перезапустить здесь, как продолжить или перерыв но он перезапускает foreach из начало его как установка счетчика цикла for В 0 снова
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
хотя очень старая нить-ни один из ответов не обратил должного внимания на семантику этого кода:
- у вас есть цепочка ограничений на
a
- если
a
ломает любой из них, попробуйте другойa
и протолкните это через цепочку.
то есть a.Change()
следует отделить от цикла проверки ограничений, также придерживаясь принципа CQS:
while (!MeetsConstraints(a))
{
a.Change();
}
bool MeetsConstraints(Thing a)
{
return Constraints.All(c => c.Allows(a));
}
нет Гото, без уродливых петель, просто простой и чистый.
void Main()
{
IEnumerable<Constrain> cons;
SomeObject a;
while(!TryChangeList(cons, a)) { }
}
// the name tryChangeList reveals the intent that the list will be changed
private bool TryChangeList(IEnumerable<Constrain> constrains, SomeObject a)
{
foreach(var con in constrains)
{
if(!c.Allows(a))
{
a.Change();
return false;
}
}
return true;
}
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}