C# 15 ganha break e continue com rótulo no .NET 11 Preview 7
break e continue com rótulo chegaram na seção de C# do .NET 11 Preview 7. Agora você pode colocar um rótulo em um laço e saltar direto para ele, o que aposenta as gambiarras com flag booleana e goto em laços aninhados.
O .NET 11 Preview 7 saiu em 2026-08-11, e a seção de C# traz um recurso que a comunidade pede há muito tempo: break e continue agora podem nomear um rótulo em um laço ou switch que os contenha. A proposta apadrinhada é a dotnet/csharplang#9875, e a lista de discussões anexada a ela liga nove tópicos distintos da comunidade que remontam a anos atrás.
Como a sintaxe se parece
O rótulo fica diretamente no laço, e a instrução de salto o nomeia:
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;
}
}
}
Um único rótulo serve para os dois saltos. Sem rótulo, break e continue se comportam exatamente como antes e miram a instrução aplicável mais interna, então isso é puramente aditivo.
As duas gambiarras que ele substitui
A versão com flag booleana precisa de estado que existe só para propagar a saída para fora, e ele tem que ser verificado em cada nível:
bool found = false;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (i * j > 20)
{
found = true;
break;
}
}
if (found)
break;
}
A versão com goto é pior no caso do continue, porque o rótulo precisa ficar no fim do corpo do laço para que o incremento e a condição ainda rodem:
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
if (j == 5)
goto next;
}
next: ; // The empty statement is required.
}
Isso é frágil. Qualquer instrução inserida sem querer entre o rótulo e a chave de fechamento muda silenciosamente o que o salto faz. Amarrar o rótulo à própria construção do laço elimina esse modo de falha.
Duas regras que vale conhecer antes de refatorar
Somente a instrução imediatamente aninhada dentro de uma instrução rotulada recebe o rótulo. Dado a: b: while (...) ..., apenas b rotula o laço. a rotula a instrução rotulada interna, que não é ela própria um laço, então break a; dentro daquele corpo é um erro de compilação em vez de um salto para o while. A especificação rejeita explicitamente rótulos aninhados.
Além disso, break pode mirar um switch que o contenha, mas continue não. continue sempre se resolve para uma instrução de iteração, o que decorre do significado de cada um dos saltos.
O analisador que encontra seus casos existentes
Você não precisa caçar manualmente o código que se qualifica. O IDE0410 (“Use labeled jump statement”) sinaliza os três padrões: um goto que pula para além de um laço aninhado, um goto para um rótulo vazio no fim, e a cadeia de propagação com flag booleana. Ele vem ligado por padrão via csharp_style_prefer_labeled_jump_statements = true e vale para C# 15 em diante. Desligue por projeto com:
[*.cs]
dotnet_diagnostic.IDE0410.severity = none
Você precisa do SDK de prévia do .NET 11 para testar, igual aos indexadores de extensão que chegaram no Preview 6. Os detalhes completos estão na especificação do recurso e no anúncio do Preview 7.
Comments
Sign in with GitHub to comment. Reactions and replies thread back to the comments repo.