BRO1143: No 'else' after a branch that ends in a jump¶
When the if branch ends in return, throw, break, continue, goto or yield break, the else is not needed:
its body can follow the if statement. Not a StyleCop rule: from Meziantou's
MA0071 and Roslynator's
RCS1211. Off by default, also in the preset.
Example¶
root = true
[*.cs]
dotnet_diagnostic.BRO1143.severity = warning
Before¶
public static class Pricing
{
public static decimal Price(decimal amount, bool member)
{
if (amount <= 0)
{
return 0;
}
else
{
var discount = member ? 0.1m : 0m;
return amount * (1 - discount);
}
}
}
After¶
public static class Pricing
{
public static decimal Price(decimal amount, bool member)
{
if (amount <= 0)
{
return 0;
}
var discount = member ? 0.1m : 0m;
return amount * (1 - discount);
}
}
Why¶
The early return is a guard: after it, the normal path continues at the method's own level instead of one level
deeper. It's a matter of taste, though: some teams prefer the symmetric if/else when both branches are equally
important. That's why the rule is off by default; turn it on with dotnet_diagnostic.BRO1143.severity = warning.
How the fix works¶
It removes the else (and the braces of its block) and moves the body one indentation level out, below the if
statement. Indentation follows indent_style/indent_size. When the if branch is a multi-line block,
BRO1519 wants a blank line after its }, and the fix adds it. An else body that contains another such
if/else is fixed in the same pass: every line moves out once per else it leaves.
When the if branch has no braces and BRO1514-BRO1516 want braces on it (for example
BRO1516, because the else block makes the chain inconsistent), the fix adds them too, so the result is the same
whichever rule dotnet format runs first:
if (x)
return 1;
else
{
return 2;
}
becomes
if (x)
{
return 1;
}
return 2;
"Ends in a jump" is decided by syntax: the branch is a jump statement, a block whose last statement ends in one, or an
if/else whose branches both end in one (so an outer and an inner else go in the same run). Loops, switch and
try don't count.
Not reported¶
else ifchains (if (a) return 1; else if (b) return 2; else return 3;): removing the firstelsewould leave a new candidate for a second run. Only anifwhoseelseis not anotherif.- An
ifthat isn't a statement of a block (the branch of anotherif, acasesection's statement list, a label's statement), or that doesn't start its line. - An empty
elseblock. - Comments or directives around the
else: between theifbranch and the first statement of the body, or between the body's last statement and its}. And any#ifin the whole statement. - A body that starts on the
elseline but goes on below it, a body whose lines aren't indented one level deeper than theif, and strings or/* */comments spanning lines (their inner lines can't be moved out). usingdeclarations in the body (using var x = ...;): moved out, they would be disposed at the end of the enclosing block instead of theelseblock.- Names declared in the body (locals, local functions, pattern variables, lambda parameters, labels) that the enclosing block also uses: they would clash there.
- An
ifbranch without braces that a brace rule wants braces on but can't add (a comment or directive where the{would go, a string spanning lines): see How the fix works.
Compared with StyleCop¶
StyleCop has no such rule. stylebro-migrate leaves it off.