break

在循环(for, foreach, do, while)中,break 语句中止最内层循环的执行并返回到它之后的代码。它也可以与 yield 一起使用,其中它指定迭代器已经结束。

for (var i = 0; i < 10; i++)
{
    if (i == 5)
    {
        break;
    }
    Console.WriteLine("This will appear only 5 times, as the break will stop the loop.");
}

.NET 小提琴现场演示

foreach (var stuff in stuffCollection)
{
    if (stuff.SomeStringProp == null)
        break;
    // If stuff.SomeStringProp for any "stuff" is null, the loop is aborted.
    Console.WriteLine(stuff.SomeStringProp);
}

break-statement 也用于 switch-case 结构中,以退出 case 或 default 段。

switch(a)
{
    case 5:
        Console.WriteLine("a was 5!");
        break;

    default:
        Console.WriteLine("a was something else!");
        break;
}

在 switch 语句中,每个 case 语句的末尾都需要’bre​​ak’关键字。这与允许落入系列中的下一个 case 语句的某些语言相反。解决方法包括’goto’语句或按顺序堆叠’case’语句。

以下代码将给出数字 0, 1, 2, ..., 9,最后一行不会被执行。yield break 表示函数的结束(不仅仅是循环)。

public static IEnumerable<int> GetNumbers()
{
    int i = 0;
    while (true) {
        if (i < 10) {
            yield return i++;
        } else {
            yield break;
        }
    }
    Console.WriteLine("This line will not be executed");
}

.NET 小提琴现场演示

请注意,与其他一些语言不同,无法在 C#中标记特定的中断。这意味着在嵌套循环的情况下,只会停止最里面的循环:

foreach (var outerItem in outerList)
{
    foreach (var innerItem in innerList)
    {
        if (innerItem.ShoudBreakForWhateverReason)
            // This will only break out of the inner loop, the outer will continue:
            break; 
    }
}

如果你想在此处突破外部循环,可以使用以下几种策略之一,例如:

  • 一个跳转语句来跳出整个循环结构。
  • 一个特定的标志变量(以下示例中为 shouldBreak),可以在外循环的每次迭代结束时检查。
  • 重构代码以在最内层循环体中使用 return 语句,或者完全避免整个嵌套循环结构。
bool shouldBreak = false;
while(comeCondition)
{
    while(otherCondition)
    {
        if (conditionToBreak)
        {
            // Either tranfer control flow to the label below...
            goto endAllLooping;

            // OR use a flag, which can be checked in the outer loop:
            shouldBreak = true;
        }
    }

    if(shouldBreakNow)
    {
        break; // Break out of outer loop if flag was set to true
    }
}

endAllLooping: // label from where control flow will continue