如何在 C# 中没有标志变量的情况下跳出 2 个循环?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/982595/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 04:51:03  来源:igfitidea点击:

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

c#syntax

提问by Matthew Vines

As a trivial example lets say I have the following grid and I am looking for a particular cells value. When found I no longer need to process the loops.

作为一个简单的例子,假设我有以下网格,我正在寻找一个特定的单元格值。找到后,我不再需要处理循环。

foreach(DataGridViewRow row in grid.Rows)
{
    foreach(DataGridViewCell cell in row.Cells)
    {
        if(cell.Value == myValue)
        {
            //Do Something useful
            //break out of both foreach loops.
        }
    }
}

How is this done in C#. In Java I could use a label to name the outermost loop, and then break that loop, but I can't seem to find an equivelant in C#.

这是如何在 C# 中完成的。在 Java 中,我可以使用标签来命名最外层循环,然后中断该循环,但我似乎无法在 C# 中找到等效项。

What is the tersest way of accomplishing this in c#? I know I can set a boolean flag, and check it in the outer loop to break out of that one as well, but it just seems too verbose.

在 c# 中完成此操作的最简洁方法是什么?我知道我可以设置一个布尔标志,并在外循环中检查它以摆脱那个标志,但这似乎太冗长了。

Thanks,

谢谢,

采纳答案by mqp

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 CheckWhateverinto the loop condition, too.) This is just a verbose demonstration of the principle.

当然,您可以使用 LINQ 或其他任何东西来简化它(您也可以将其CheckWhatever放入循环条件中。)这只是对原理的详细演示。

回答by PeterAllenWebb

C# does have a goto statement. In fact, the example on MSDN uses it to break out of a doubly-nested loop.

C#确实有一个 goto 语句。实际上,MSDN 上的示例使用它来跳出双嵌套循环。

回答by Paul Sonier

The best way is to not do this. Seriously; if you want to find the first occurrence of something in your nested loops, and then finish looking, then what you want to do is NOT to examine each element, which is explicitly just what the foreach construct does. I'd recommend using a regular for loop with a termination flag in the loop invariant.

最好的方法是不要这样做。严重地; 如果您想在嵌套循环中找到某事的第一次出现,然后完成查找,那么您要做的不是检查每个元素,这显然正是 foreach 构造所做的。我建议在循环不变量中使用带有终止标志的常规 for 循环。

回答by JB King

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

我只是将循环包装到一个函数中,并让函数返回作为退出我的解决方案循环的一种方式。

回答by J.W.

  1. Use go to as PeterAllenWebb as suggested.
  2. Wrap the two for each loop into a function, and return when you want to break.
  1. 按照建议使用转到 PeterAllenWebb。
  2. 将每个循环的两个包装成一个函数,要中断时返回。

Did a bit google search, here is a similar questionon MSDN forum.

做了一点谷歌搜索,这是MSDN 论坛上的类似问题

回答by Timothy Carter

        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.

编辑:只是在这里添加一点警告;使用 goto 通常被认为是不好的做法,因为它们很快会导致(几乎)无法维护的意大利面条式代码。话虽如此,它已包含在 C# 语言中,并且可供使用,因此显然有人相信它具有有效的用法。知道该功能存在并谨慎使用。

回答by Jimmy

1

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

2

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

3

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
}

回答by Amy B

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

回答by shahkalpesh

Put that into a function & use a returnstatement, when things are found.
At the end of it return a null value - indicating searched item not found.

return当找到东西时,将其放入函数并使用语句。
在它的末尾返回一个空值 - 表示未找到搜索的项目。

回答by Alan Hymanson

You could modify your loop variable:

您可以修改循环变量:

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

}