What a redundant else is
An else is redundant when the if branch above it always ends the method with return. If that branch runs, nothing after it can run. If it does not run, execution simply continues to the next line. So the else adds braces and an extra level of indentation without changing what the program does.
Here is the method this lesson starts with:
class Solution {
public int Negative(int n) {
if (n < 0) {
return n;
} else {
return -n;
}
}
}
It works correctly: a negative n comes back unchanged, and anything else is negated. But look at the flow. When n < 0, the method returns on the first return and ends. The only way to reach return -n; is if the condition was false. The else says that out loud, but the structure already implies it.
The cleanup
Delete the else and its braces, and keep the second return after the if block:
class Solution {
public int Negative(int n) {
if (n < 0) {
return n;
}
return -n;
}
}
The behaviour is identical. For -4 the method returns -4 from inside the if. For 4 the condition is false, C# skips the block, and the next line returns -4. For 0 it also reaches the final return and gives 0.
Why it is worth doing
- Less nesting. The main path of the method is no longer indented inside an
else. With larger methods, deep nesting makes code hard to follow. - The special case reads first. The
ifhandles a case and leaves; everything after it is the normal path. This pattern is often called an early return or a guard clause. - Fewer places to make mistakes. There are fewer braces to match and fewer branches to track.
When you cannot remove the else
The trick only works when the if branch ends the method. If the branch just prints, or assigns a variable, execution falls through to the code after it. Removing the else would then make that code run in both cases. For example:
if (n < 0) {
Console.WriteLine("negative");
} else {
Console.WriteLine("positive");
}
Without the else, a negative number would print both lines. The same holds if the if branch ends with something that does not leave the method; return does, and so does throw.
The exercise, step by step
- Check that the first branch always returns.
return n;is the only statement in theifblock, so entering the block always ends the method. - Remove the
elsekeyword and its braces. Leave the closing brace of theifblock in place. - Keep
return -n;at the same level as theif, directly after it, inside the method.
Checking the result
After a refactoring like this, test that nothing changed. Run the method on a negative number, on zero and on a positive number, and compare with the old version. For -5, 0 and 5 both versions return -5, 0 and -5. A change that keeps the behaviour identical while improving the shape of the code is what programmers call a refactoring, and having tests to confirm it is what makes it safe.
Common mistakes
- Removing the second
returnalong with theelse. Then the method has a path that returns nothing, and C# refuses to compile it. - Leaving a stray brace. Taking out
else {also takes out its closing brace. Theifkeeps its own closing brace, and the method needs its own too. - Applying it to branches that do not return. Check first that the
ifblock really leaves the method.
Key takeaways
- If an
ifblock always returns, theelseafter it is unnecessary. - Removing it keeps the behaviour the same and makes the code flatter.
- Only do this when the branch really leaves the method.