How to break out of 2 loops without a flag variable in C#?

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
}

Though many of the solutions above are correct and answer your question, I would take a step back and ask myself "is there another way to more clearly represent the semantics of the program?"

I would be inclined to write the code like this:

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

Why write any loops at all? You want to know if a particular collection has a particular member, so write a query that asks that question, and then examine the answer.


The most pleasant way is to break the second loop out into a function, like this:

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
        }
    }
}

goes to

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;
    }
}

Of course, feel free to simplify this with LINQ or whatever (you could put CheckWhatever into the loop condition, too.) This is just a verbose demonstration of the principle.


I'd just wrap the loops into a function and have the function return as a way to exit the loops for my solution.


        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: ;

that will work, but I would recommend using a boolean flag.

EDIT: Just to add a little more warning here; it is generally considered bad practice to use goto's as they quickly can lead to spaghetti code that is (nearly) impossible to maintain. That being said, it was included in the C# language, and is available for use, so clearly there are people who believe it has valid usages. Know that the feature exists and use with great caution.