Как убежать из 2 циклов без переменной флага в C#?

Вы пробовали это?

int MCC = RadioInfo.getMCC(RadioInfo.getCurrentNetworkIndex());
int MNC = RadioInfo.getMNC(RadioInfo.getCurrentNetworkIndex());
int LAC = GPRSInfo.getCellInfo().getLAC();
int CELLID = GPRSInfo.getCellInfo().getCellId();
42
задан Matthew Vines 11 June 2009 в 17:48
поделиться

13 ответов

Самый приятный способ - разбить второй цикл на функцию, например:

public void DoubleLoop()
{
    for(int i = 0; i < width; i++)
    {
        for(int j = 0; j < height; j++)
        {
            if(whatever[i][j]) break; // let's make this a "double" break
        }
    }
}

переходит к

public bool CheckWhatever(int whateverIndex)
{
    for(int j = 0; j < height; j++)
    {
        if(whatever[whateverIndex][j]) return false;
    }

    return true;
}

public void DoubleLoop()
{
    for(int i = 0; i < width; i++)
    {
        if(!CheckWhatever(i)) break;
    }
}

Конечно, не стесняйтесь упрощать это с помощью LINQ или чего-то еще (вы также можно поместить CheckWhatever в условие цикла.) Это просто подробная демонстрация принципа.

36
ответ дан 26 November 2019 в 23:12
поделиться

Вы можете изменить свою переменную цикла:

for (int i = 0; i < width; i++)
{
    for (int j = 0; j < height; j++)
    {
        if (NeedToBreak())
        {
            i = width;
            j = height; 
        }
    }

}
0
ответ дан 26 November 2019 в 23:12
поделиться

Поместите это в функцию и используйте оператор return , когда что-то будет найдено.
В конце возвращается нулевое значение, указывающее, что искомый элемент не найден.

1
ответ дан 26 November 2019 в 23:12
поделиться
  //describe how to find interesting cells
var query = from row in grid.Rows.OfType<DataGridViewRow>()
            from cell in row.Cells.OfType<DataGridViewCell>()
            where cell.Value == myValue
            select cell;
  //nab the first cell that matches, if any
DataGridViewCell theCell = query.FirstOrDefault();

  //see if we got one
if (theCell != null)
{
  //Do something with theCell
}
2
ответ дан 26 November 2019 в 23:12
поделиться
  1. Используйте go to как PeterAllenWebb, как было предложено.
  2. Оберните два для каждого цикла в функцию и возвращайте, когда вы хотите прервать работу.

Сделал небольшой поиск в Google, вот это аналогичный вопрос на форуме MSDN.

2
ответ дан 26 November 2019 в 23:12
поделиться

Лучше всего этого не делать. Шутки в сторону; если вы хотите найти первое вхождение чего-либо во вложенных циклах, а затем закончить поиск, то вам нужно НЕ проверять каждый элемент, что явно соответствует тому, что делает конструкция foreach. Я бы рекомендовал использовать обычный цикл for с флагом завершения в инварианте цикла.

8
ответ дан 26 November 2019 в 23:12
поделиться

В C # есть оператор goto . Фактически, в примере на MSDN он используется для выхода из двояковложенного цикла.

11
ответ дан 26 November 2019 в 23:12
поделиться

Для полноты картины существует также неправильный способ сделать это:

try
{
    foreach(DataGridViewRow row in grid.Rows)
        foreach(DataGridViewCell cell in row.Cells)
            if(cell.Value == myValue)
               throw new FoundItemException(cell);
}
catch (FoundItemException ex)
{
    //Do Something useful with ex.item
}
14
ответ дан 26 November 2019 в 23:12
поделиться
        foreach (DataGridViewRow row in grid.Rows)
        {
            foreach (DataGridViewCell cell in row.Cells)
            {
                if (cell.Value == myValue)
                {
                    goto EndOfLoop;
                    //Do Something useful
                    //break out of both foreach loops.
                }
            }

        }
        EndOfLoop: ;

, который будет работать, но я бы рекомендовал использовать логический флаг.

РЕДАКТИРОВАТЬ: Просто чтобы добавить сюда еще одно предупреждение; обычно считается плохой практикой использовать goto, поскольку они быстро могут привести к спагетти-коду, который (почти) невозможно поддерживать. При этом он был включен в язык C # и доступен для использования, поэтому очевидно, что есть люди, которые считают, что он имеет допустимое использование. Знайте, что эта функция существует, и используйте ее с большой осторожностью.

19
ответ дан 26 November 2019 в 23:12
поделиться

Я бы просто обернул циклы в функцию и получил бы функцию возврата как способ выхода из циклов для моего решения.

23
ответ дан 26 November 2019 в 23:12
поделиться

Хотя многие из приведенных выше решений верны и отвечают на ваш вопрос, я хотел бы сделать шаг назад и спросить себя «есть ли другой способ более четко представить семантику программы? "

Я был бы склонен написать такой код:

var query = from row in grid.Rows
            from cell in row.Cells
            where cell.Value == myValue
            select cell;
if (query.Any())
{
  // do something useful;
}

Зачем вообще писать какие-либо циклы? Вы хотите знать, есть ли в определенной коллекции определенный член, поэтому напишите запрос, который задает этот вопрос, а затем изучите ответ.

57
ответ дан 26 November 2019 в 23:12
поделиться

1

foreach(DataGridViewRow row in grid.Rows)
   foreach(DataGridView cell in row.Cells)
      if (cell.Value == somevalue) {
         // do stuff
         goto End;
      }
End:
   // more stuff

2

void Loop(grid) {
    foreach(row in grid.Rows)
       foreach(cell in row.Cells)
           if (something) {
               // do stuff   
               return;
           }
}

3

var cell = (from row in grid.Rows.OfType<DataGridViewRow>()
            from cell in row.Cells.OfType<DataGridViewCell>()
            where cell.Value == somevalue
            select cell
   ).FirstOrDefault();

if (cell != null) {
   // do stuff
}
66
ответ дан 26 November 2019 в 23:12
поделиться

Вы можете написать класс, реализующий IEnumerator в общем случае, и тогда ваш код перечисления будет выглядеть так:

foreach (Foo foo in someClass.Items) {
    foreach (Bar bar in foo.Items) {
        foreach (Baz baz in bar.Items) {
            yield return baz;
        }
    }
}

// and later in client code

MyEnumerator e = new MyEnumerator(someClass);
foreach (Baz baz in e) {
    if (baz == myValue) {
        // do something useful
        break;
    }
 }
5
ответ дан 26 November 2019 в 23:12
поделиться
Другие вопросы по тегам:

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