Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions docfx.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"csharp-14.0/*.md",
"closed-hierarchies.md",
"collection-expression-arguments.md",
"labeled-break-continue.md",
"unions.md",
"unsafe-evolution.md"
],
Expand Down Expand Up @@ -648,6 +649,7 @@
"_csharplang/proposals/collection-expression-arguments.md": "Collection expression arguments",
"_csharplang/proposals/unions.md": "Unions",
"_csharplang/proposals/closed-hierarchies.md": "Closed hierarchies",
"_csharplang/proposals/labeled-break-continue.md": "Labeled break and continue",
"_csharplang/proposals/unsafe-evolution.md": "Memory safety",
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "C# compiler breaking changes since C# 10",
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "C# compiler breaking changes since C# 11",
Expand Down Expand Up @@ -733,6 +735,7 @@
"_csharplang/proposals/collection-expression-arguments.md": "This proposal introduces collection expression arguments.",
"_csharplang/proposals/unions.md": "This proposal describes union types and union declarations. Unions allow expressing values from a closed set of types with exhaustive pattern matching.",
"_csharplang/proposals/closed-hierarchies.md": "This proposal describes closed class hierarchies. A closed class restricts derivation to its declaring assembly, enabling exhaustive `switch` expressions over its direct descendants.",
"_csharplang/proposals/labeled-break-continue.md": "This proposal allows `break` and `continue` statements to optionally target an enclosing labeled loop or `switch` statement, enabling cleaner control flow in nested constructs without `goto`.",
"_csharplang/proposals/unsafe-evolution.md": "This proposal describes the evolution of memory safety in C#. It ties the `unsafe` context to operations that access unmanaged memory, rather than to the existence of pointer types.",
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 7.md": "Learn about any breaking changes since the initial release of C# 10 and included in C# 11",
"_roslyn/docs/compilers/CSharp/Compiler Breaking Changes - DotNet 8.md": "Learn about any breaking changes since the initial release of C# 11 and included in C# 12",
Expand Down
12 changes: 11 additions & 1 deletion docs/csharp/language-reference/statements/jump-statements.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ helpviewer_keywords:
---
# Jump statements - `break`, `continue`, `return`, and `goto`

The jump statements unconditionally transfer control. The [`break` statement](#the-break-statement) terminates the closest enclosing [iteration statement](iteration-statements.md) or [`switch` statement](selection-statements.md#the-switch-statement). The [`continue` statement](#the-continue-statement) starts a new iteration of the closest enclosing [iteration statement](iteration-statements.md). The [`return` statement](#the-return-statement) terminates execution of the function in which it appears and returns control to the caller. The [`goto` statement](#the-goto-statement) transfers control to a statement that is marked by a label.
The jump statements unconditionally transfer control. The [`break` statement](#the-break-statement) terminates the closest enclosing [iteration statement](iteration-statements.md) or [`switch` statement](selection-statements.md#the-switch-statement), or an enclosing labeled iteration or `switch` statement. The [`continue` statement](#the-continue-statement) starts a new iteration of the closest enclosing [iteration statement](iteration-statements.md), or an enclosing labeled iteration statement. The [`return` statement](#the-return-statement) terminates execution of the function in which it appears and returns control to the caller. The [`goto` statement](#the-goto-statement) transfers control to a statement that is marked by a label.

For information about the `throw` statement that throws an exception and unconditionally transfers control as well, see [The `throw` statement](exception-handling-statements.md#the-throw-statement) section of the [Exception-handling statements](exception-handling-statements.md) article.

Expand All @@ -35,6 +35,10 @@ In nested loops, the `break` statement terminates only the innermost loop that c

:::code language="csharp" source="snippets/jump-statements/BreakStatement.cs" id="NestedLoop":::

Starting in C# 15, a `break` statement can optionally specify a label that identifies an enclosing loop or `switch` statement to exit. Place the label directly on the target construct, as in `outer: for (...)`, then use `break outer;` from within a nested construct to transfer control to the statement that follows the labeled construct, as the following example shows:

:::code language="csharp" source="snippets/jump-statements/BreakStatement.cs" id="LabeledBreak":::

When you use the `switch` statement inside a loop, a `break` statement at the end of a switch section transfers control only out of the `switch` statement. The loop that contains the `switch` statement is unaffected, as the following example shows:

:::code language="csharp" source="snippets/jump-statements/BreakStatement.cs" id="SwitchInsideLoop":::
Expand All @@ -45,6 +49,12 @@ The `continue` statement starts a new iteration of the closest enclosing [iterat

:::code language="csharp" source="snippets/jump-statements/ContinueStatement.cs" id="BasicExample":::

Starting in C# 15, a `continue` statement can optionally specify a label that identifies an enclosing iteration statement to continue. The target must be a loop; `continue` doesn't target a `switch` statement. Place the label directly on the target loop, as in `outer: for (...)`, then use `continue outer;` from within a nested construct to start the next iteration of that loop, as the following example shows:

:::code language="csharp" source="snippets/jump-statements/ContinueStatement.cs" id="LabeledContinue":::

For both labeled `break` and labeled `continue`, only the statement immediately nested in a labeled statement has that label. For example, in `a: b: while (...)`, the `while` statement is labeled `b`, not `a`.

## The `return` statement

The `return` statement terminates execution of the function where it appears. It returns control and the function's result, if any, to the caller.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
{
BasicExample();
NestedLoop();
LabeledBreak();
SwitchInsideLoop();
}

Expand Down Expand Up @@ -55,6 +56,39 @@
// </NestedLoop>
}

private static void LabeledBreak()
{
// <LabeledBreak>
string[,] stockChecks =
{
{ "Clear", "Clear", "Clear" },
{ "Clear", "Blocked", "Clear" },
{ "Clear", "Clear", "Clear" }
};

outer: for (int aisle = 0; aisle < stockChecks.GetLength(0); aisle++)
{
for (int bay = 0; bay < stockChecks.GetLength(1); bay++)
{
Console.WriteLine($"Checking aisle {aisle}, bay {bay}.");

if (stockChecks[aisle, bay] == "Blocked")
{
Console.WriteLine("Blocked bay found. Stop the inspection.");
break outer;

Check failure on line 78 in docs/csharp/language-reference/statements/snippets/jump-statements/BreakStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

D:\a\docs\docs\docs\csharp\language-reference\statements\snippets\jump-statements\BreakStatement.cs(78,27): error CS8652: The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. [D:\a\docs\docs\docs\csharp\language-reference\statements\snippets\jump-statements\jump-statements.csproj]

Check failure on line 78 in docs/csharp/language-reference/statements/snippets/jump-statements/BreakStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.

Check failure on line 78 in docs/csharp/language-reference/statements/snippets/jump-statements/BreakStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.

Check failure on line 78 in docs/csharp/language-reference/statements/snippets/jump-statements/BreakStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
}
Comment on lines +69 to +79
}
}
// Output:
// Checking aisle 0, bay 0.
// Checking aisle 0, bay 1.
// Checking aisle 0, bay 2.
// Checking aisle 1, bay 0.
// Checking aisle 1, bay 1.
// Blocked bay found. Stop the inspection.
// </LabeledBreak>
}

private static void SwitchInsideLoop()
{
// <SwitchInsideLoop>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
public static void Examples()
{
BasicExample();
LabeledContinue();
}

private static void BasicExample()
Expand All @@ -30,4 +31,46 @@
// Iteration 4: done
// </BasicExample>
}

private static void LabeledContinue()
{
// <LabeledContinue>
string[][] dailyRoutes =
[
["North", "West"],
["South", "Bridge closed", "East"],
["Central", "Harbor"]
];

outer: for (int day = 0; day < dailyRoutes.Length; day++)
{
Console.WriteLine($"Day {day + 1}:");

foreach (string route in dailyRoutes[day])
{
if (route == "Bridge closed")
{
Console.WriteLine(" Bridge closed; move to the next day.");
continue outer;

Check failure on line 54 in docs/csharp/language-reference/statements/snippets/jump-statements/ContinueStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

D:\a\docs\docs\docs\csharp\language-reference\statements\snippets\jump-statements\ContinueStatement.cs(54,30): error CS8652: The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version. [D:\a\docs\docs\docs\csharp\language-reference\statements\snippets\jump-statements\jump-statements.csproj]

Check failure on line 54 in docs/csharp/language-reference/statements/snippets/jump-statements/ContinueStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.

Check failure on line 54 in docs/csharp/language-reference/statements/snippets/jump-statements/ContinueStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.

Check failure on line 54 in docs/csharp/language-reference/statements/snippets/jump-statements/ContinueStatement.cs

View workflow job for this annotation

GitHub Actions / snippets-build

The feature 'labeled break and continue' is currently in Preview and *unsupported*. To use Preview features, use the 'preview' language version.
}
Comment on lines +45 to +55

Console.WriteLine($" Schedule the {route} route.");
}

Console.WriteLine(" All routes scheduled.");
}
// Output:
// Day 1:
// Schedule the North route.
// Schedule the West route.
// All routes scheduled.
// Day 2:
// Schedule the South route.
// Bridge closed; move to the next day.
// Day 3:
// Schedule the Central route.
// Schedule the Harbor route.
// All routes scheduled.
// </LabeledContinue>
}
}
2 changes: 2 additions & 0 deletions docs/csharp/specification/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ items:
href: ../../../_csharplang/proposals/csharp-13.0/lock-object.md
- name: Allow `ref` and `unsafe`
href: ../../../_csharplang/proposals/csharp-13.0/ref-unsafe-in-iterators-async.md
- name: Labeled `break` and `continue`
href: ../../../_csharplang/proposals/labeled-break-continue.md
- name: Classes
items:
- name: Partial properties
Expand Down
27 changes: 27 additions & 0 deletions docs/csharp/whats-new/csharp-15.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ C# 15 includes the following new features. Try these features by using the lates
- [Union types](#union-types)
- [Closed hierarchies](#closed-hierarchies)
- [Extension indexers](#extension-indexers)
- [Labeled `break` and `continue`](#labeled-break-and-continue)
- [Memory safety](#memory-safety)

C# 15 is the latest C# preview release. .NET 11 preview versions support C# 15. For more information, see [C# language versioning](../language-reference/configure-language-version.md).
Expand Down Expand Up @@ -134,6 +135,32 @@ int third = numbers[2];

For more information, see [Extension declaration](../language-reference/keywords/extension.md#extension-indexers) in the language reference or the [feature specification](~/_csharplang/proposals/extension-indexers.md).

## Labeled `break` and `continue`

Starting with C# 15, `break` and `continue` statements can name a label on an enclosing construct. Use a labeled `break` to exit an enclosing loop or `switch` statement. Use a labeled `continue` to start the next iteration of an enclosing loop.

```csharp
outer: for (int row = 0; row < grid.Height; row++)
{
for (int column = 0; column < grid.Width; column++)
{
if (grid[row, column].IsBlocked)
{
continue outer;
}

if (grid[row, column].IsGoal)
{
break outer;
}
}
}
```
Comment on lines +142 to +158

The label is placed directly on the loop or `switch` statement it identifies. Without a label, `break` and `continue` keep their existing behavior and target the innermost applicable statement.

For more information, see [Jump statements](../language-reference/statements/jump-statements.md) in the language reference or the [feature specification](~/_csharplang/proposals/labeled-break-continue.md).

## Memory safety

C# 15 begins a multirelease effort to redefine memory safety in the language. The goal is to tie the `unsafe` context to the operations that actually access unmanaged memory, rather than to the existence of pointer types. Most memory safety vulnerabilities come from these access operations, so the language makes them stand out for reviewers and auditors.
Expand Down
Loading