Перезапустить цикл foreach в С#?
Как перезапустить цикл foreach
в С#?
Например:
Action a;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart;
}
}
restart
здесь как continue
или break
, но он перезапускает foreach с начала
Это похоже на то, что снова установите счетчик цикла for
в значение 0.
Возможно ли это в С#?
Изменить: я хочу поблагодарить Мехрдада Афшари и Махеша Велага за то, что позволил мне обнаружить ошибку (index = 0) в моей текущей реализации, которая не была бы обнаружена иначе.
Ответы
Ответ 1
Используйте старый добрый goto
:
restart:
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
goto restart;
}
}
Если вам почему-то поставлен диагноз "гофтофобия" в 100% случаев (что небезопасно без причины), вы можете попробовать вместо этого использовать флаг:
bool restart;
do {
restart = false;
foreach(Constrain c in Constrains)
{
if(!c.Allows(a))
{
a.Change();
restart = true;
break;
}
}
} while (restart);
Ответ 2
Один из способов, которым вы можете это сделать, использовать, как вы уже упоминали:
перезагрузка здесь похоже на продолжение или разрыв но он перезапускает foreach из начало Это , как установка счетчика цикла for в 0 снова
Action a;
for(var index = 0; index < Constratins.Count; index++)
{
if(!Constraints[index].Allows(a))
{
a.Change();
index = -1; // restart
}
}
Ответ 3
Хотя очень старый поток - ни один из ответов не уделил должного внимания семантике этого кода:
- У вас есть цепочка ограничений на
a
- Если
a
сломает любой из них, попробуйте еще один a
и нажмите это через цепочку.
То есть, a.Change()
следует отделить от цикла проверки ограничений, также придерживаясь принципа CQS:
while (!MeetsConstraints(a))
{
a.Change();
}
bool MeetsConstraints(Thing a)
{
return Constraints.All(c => c.Allows(a));
}
Нет goto, никаких уродливых петель, просто и чисто. </сама-обратно-пощечина >
Ответ 4
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;
}
Ответ 5
for (var en = Constrains.GetEnumerator(); en.MoveNext(); )
{
var c = en.Current;
if (!c.Allows(a))
{
a.Change();
en = Constrains.GetEnumerator();
}
}