5

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;
    }
}
  • 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. – Thomas Eding Jan 28 '15 at 23:21
  • 5
    @ThomasEding: Visual Studio issues an "unreachable code detected" warning if you do that. – Robert Harvey Jan 28 '15 at 23:22
  • @RobertHarvey: Interesting. I've never encountered that problem before (or so I believe). – Thomas Eding Jan 28 '15 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 '15 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. – Sebastian Redl Jan 30 '15 at 12:26
12

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.

  • ...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 '15 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.

  • 1
    That seems like a really artificial reason to rearrange the code and introduce indirection. – Doval Jan 30 '15 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 '15 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 '15 at 18:06
  • Does a breakpoint on the closing brace of the function not work for you? – Deduplicator Jan 31 '15 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 '15 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.

protected by gnat Jan 30 '15 at 14:17

Thank you for your interest in this question. Because it has attracted low-quality or spam answers that had to be removed, posting an answer now requires 10 reputation on this site (the association bonus does not count).

Would you like to answer one of these unanswered questions instead?

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