7

When using the Switch statement, is using return instead of break or a combination of the two considered bad form?

while (true)
{
    var operation = Randomness.Next(0, 3);
    switch (operation)
    {
        case 0:
            return result + number;
        case 1:
            if ((result - number) > 0)
            {
                return result - number;
            }
            break;
        case 2:
            return result * number;
        case 3:
            if ((result % number) == 0)
            {
                return result / number;
            }
            break;
    }
}
6
  • 1
    I would typically use a break even if there is a guaranteed return in case (pun!) a refactor breaks (another pun! I'm on fire!) that assumption. Jan 28, 2015 at 23:21
  • 5
    @ThomasEding: Visual Studio issues an "unreachable code detected" warning if you do that. Jan 28, 2015 at 23:22
  • @RobertHarvey: Interesting. I've never encountered that problem before (or so I believe). Jan 28, 2015 at 23:22
  • You can use a combination of both (to an extent) but some IDEs might not be so coorperative with it and long term code maintenance could potentially be a nightmare
    – Roboman
    Jan 30, 2015 at 11:58
  • 2
    Furthermore, accidental fall-through after refactoring is not an issue in C#, as fall-through is a compiler error. You need an explicit goto case. Jan 30, 2015 at 12:26

3 Answers 3

13

The break statement is required in case 1 and case 3. If you omit it, the code will not compile, because the if body is not guaranteed to execute, and fall-through in switch statements is not allowed in C#.

The break statement is not required in case 0 and case 2, because the return always executes; code execution will never reach the break statement. The compiler will issue a warning if you include the break statement, but the code will compile.

Not having break statements can be useful in simplifying certain mapping or factory functions:

public string NumericString(int digit)
{
    switch (digit)
    {
        case 1: return "one";
        case 2: return "two";
        case 3: return "three";
        // ..etc.
    }
}

If you need fall-through behavior, you can simulate it with a goto, one of the few places in the C# language where using a goto actually makes sense, though it's arguable whether or not that constitutes good style.

1
  • ...can be useful in simplifying was what I was going for. I just don't recall seeing breaks and returns stacked next to each other like I did in cases 1 & 3. I know logically it does what I want. I just thought I went about it in a slightly odd fashion.
    – tyh
    Jan 28, 2015 at 23:33
5

I'd avoid using multiple return statements in a method like that for the simple reason that you'd need to put a breakpoint on every return statement to see which value is returned (and why).

It'd be better to do something like

while (true)
{
    var operation = Randomness.Next(0, 3);
    double? valueToReturn = null;

    switch (operation)
    {
        case 0:
            valueToReturn = result + number;
            break;
        case 1:
            if ((result - number) > 0)
                valueToReturn = result - number;
            break;
        case 2:
            valueToReturn = result * number;
            break;
        case 3:
            if ((result % number) == 0)
                valueToReturn = result / number;
            break;
    }

    if ( valueToReturn.HasValue )
        return valueToReturn.Value;
}

For a discussion on having multiple return statements in a function, see this StackOverflow question.

7
  • 1
    That seems like a really artificial reason to rearrange the code and introduce indirection.
    – Doval
    Jan 30, 2015 at 17:47
  • True, but were the switch statement to get more complex (e.g. more than one screen), it'd be harder to see what was happening with multiple return statements. Admittedly, when I say "It'd be better to...", I mean "I prefer to have..." as there's no general consensus on which to do.
    – Wai Ha Lee
    Jan 30, 2015 at 17:55
  • 2
    If the switch statement gets that big then adding a mutable variable to avoid return is just going to complicate things more. With a return you know for sure you're returning the value; with a mutable variable you have to make sure the code won't either throw an exception or overwrite the mutable variable after the switch but before the function returns.
    – Doval
    Jan 30, 2015 at 18:06
  • Does a breakpoint on the closing brace of the function not work for you? Jan 31, 2015 at 14:23
  • 3
    Hmm - it seems that from VS2013 onwards, you can see the value from the "Autos" window (link).
    – Wai Ha Lee
    Jan 31, 2015 at 14:48
2

I generally prefer to avoid mixing returns and breaks in switch statements. When I read through code and see a big switch statement, I may want to just skim it quickly to get an idea of what it's doing, then skip over it mentally to read the rest of the logic in the code. If every branch of the switch statement does the same thing, this is easy to do, but if some branches are returning and come are continuing then this becomes more difficult to understand. For this situation, I would prefer a solution like Wai Ha Lee's because it's easier to understand the code quickly.

Not the answer you're looking for? Browse other questions tagged or ask your own question.