BRO1514: Braces should not be omitted¶
The child statement of an if, else, for, foreach, while, do, using, lock or fixed statement is a
block. Replaces StyleCop SA1503.
Example¶
Before¶
public class Counter
{
public int Clamp(int value)
{
if (value < 0)
return 0;
return value;
}
}
After¶
public class Counter
{
public int Clamp(int value)
{
if (value < 0)
{
return 0;
}
return value;
}
}
Why¶
A statement added below an if without braces looks like part of it but always runs. Braces make the extent of every
condition and loop explicit.
How the fix works¶
The braces go at the indentation of the statement that owns them, the child statement one level deeper (from
indent_style/indent_size). { starts its own line unless csharp_new_line_before_open_brace leaves out
control_blocks; an else follows the } as csharp_new_line_before_else says; a do statement's while keeps its
line. A trailing comment stays with the statement. Nested statements are all fixed in one pass.
This rule replaces the SDK's IDE0011, whose fix breaks multi-targeted projects under dotnet format
(reported upstream as dotnet/roslyn#86000 and dotnet/roslyn#86001; see decisions).
Configuration¶
[*.cs]
# StyleCop's allowConsecutiveUsings, also for 'fixed (a) fixed (b) { }'. false: the inner 'using' or 'fixed' gets its
# own braces.
stylebro_allow_consecutive_usings = true
# Not a StyleCop setting (StyleCop issue #2252). true: a jump statement ('return', 'throw', 'break', 'continue',
# 'goto', 'yield break') on the line of its 'if' needs no braces: 'if (x) return;'. On the next line, or after
# 'else', it still gets braces. Default false.
stylebro_allow_single_line_jump_statements = false
# Not a StyleCop setting. all (default): every statement StyleCop checks. if_and_loops: if/else, for, foreach, while
# and do only, like Sonar's S121: not 'using', 'lock', 'fixed' or a foreach that deconstructs ('foreach (var (a, b) in x)').
# Applies to BRO1515 and BRO1516 too.
stylebro_braces_statements = all
# The SDK's setting, which BRO1514-BRO1516 follow:
# true (or not set): StyleCop's rules, as described here
# when_multiline: only multi-line child statements (BRO1515) and inconsistent if/else chains (BRO1516); "multi-line"
# as the SDK counts it: the statement, its header (a 'for' split over lines) or a do statement's
# 'while' part spans lines
# false: braces aren't required (nothing is reported)
csharp_prefer_braces = true
stylebro-migrate copies allowConsecutiveUsings from stylecop.json and writes csharp_prefer_braces from the
StyleCop rules that are on: true when any of SA1503, SA1519 and SA1520 is (each of BRO1514-BRO1516 is then on where
its StyleCop rule was, so exactly StyleCop's statements are reported), false when none is. Not when_multiline for
SA1519/SA1520 alone: its "multi-line" also counts a split if header, which SA1519 accepts
(#1488). A csharp_prefer_braces the repository sets
at severity silent or none isn't kept: nothing enforced it.
stylebro_allow_single_line_jump_statements narrows csharp_prefer_braces = true. With when_multiline, every
single-line child statement is already allowed, so the option changes nothing there; with false nothing is reported
anyway. The option only exempts statements from BRO1514: when another clause of the same if/else chain has or gets
braces, BRO1516 still asks for them on the jump too (if (x) return; else { ... } becomes fully braced
in one run). stylebro-migrate doesn't write it: stylecop.json has no such setting.
stylebro_braces_statements = if_and_loops is what stylebro-migrate writes for a repository that enforces Sonar's S121
(with csharp_prefer_braces = true), so BRO1514 reports nothing S121 accepts. When the StyleCop setup turns BRO1514 on
too (SA1503), StyleCop's statements stay checked and the option isn't written.
Not reported¶
- A multi-line child statement when BRO1515 is on, and a clause of an
if/elsechain where another clause has braces when BRO1516 is on: those rules report them (like StyleCop). if (x) return;(a jump statement on theifline) withstylebro_allow_single_line_jump_statements = true.using,lock,fixedand deconstructingforeachstatements withstylebro_braces_statements = if_and_loops(anifwhose child is one still gets braces around it).using (a) using (b) { }andfixed (a) fixed (b) { }: consecutiveusingstatements, and consecutivefixedstatements, share one block, unlessstylebro_allow_consecutive_usings = false(see Configuration). StyleCop only allowsusings; the SDK's IDE0011 allows both.- Comments or directives where the braces would go,
#ifin the owning statement, a multi-line string in the statement, or other code after it on its line: the fix can't place the braces safely. - A statement in a one-line block (
void M(bool x) { if (x) return; }) when BRO1508/ BRO1509 is on: expanding the block adds the braces too.
Compared with StyleCop¶
Same positions and output, apart from the cases above that are skipped.