6

Which method of returning a bool from a switch statement is preferable? I understand this may be subjective, however I feel it is important to our profession to get input on best practices :).

public bool foo(param)
{
    switch (param)
    {
        case 1:
            if (something)
            {
                return true;
            }

            return false;    
        default:
            return false;
     }
}

- OR -

public bool foo(param)
{
    bool flag = false;

    switch (param)
    {
        case 1:
            if (something)
            {
                flag = true;
            }
            break;
        default:
            break;
     }

    return flag;
}
DigitalZebra
  • 39,494
  • 39
  • 114
  • 146

8 Answers8

15

The difference here is between single point of return and multiple points of return.

Generally, single point of return code tends to do a lot of bookkeeping (temporary variables, checking of those variables in loops), and can get hairy as the logic gets more complex. I've seen code that goes to great lengths to use a while (flag) ... flag = false; pattern instead of a while (true) ... break; pattern, and it is not fun to read.

I prefer multiple points of return since they return as early as possible (no extra work done) and don't require any locals to help keep track of the current return value. Also, I don't find them any harder to read than single point of return code.

There's a good disucssion of this on c2 (SingleFunctionExitPoint).

I've found that keeping methods as "functional" as possible is a good thing (I say "functional" here because I'm typically doing C# which, outside of LINQ, is not considered functional). By "functional", I mean that I try to avoid mutating state as much as possible. Introducing more state in the form of locals or members makes things more difficult to understand since you now have to take into consideration their values and you have to consider how those variables can be set (from another method, from another class, ...).

In general, state is evil, but sometimes it's a necessary evil.

This particular issue has some interesting conversation here on SO as well.

Community
  • 1
  • 1
Chris Schmich
  • 29,128
  • 5
  • 77
  • 94
  • 1
    I agree with the multiple points of return and would go as far as saying that if you have to use flags to route the execution path, that could should be refactored into a method that uses multiple returns instead – Arne Claassen Aug 27 '10 at 22:37
6

I prefer the second method.
It is much more adaptable, you can for example add some work at the end of the function which will depend on flag

Also, if you only have one case, you may want to move to something other than a switch

Jean-Bernard Pellerin
  • 12,556
  • 10
  • 57
  • 79
  • Reaching a `return` statement doesn't cause the function to return immediately. Rather the compiler will automatically call destructors for local variables. This is the preferred way to have end-of-function cleanup in C++. – Ben Voigt Aug 27 '10 at 22:51
  • 1
    If you have work that depends on flag, that might be a sign your function is doing too much. – Dykam Aug 28 '10 at 09:37
  • @Ben Voigt, this is about C# which doesn't have things like destructors, and if it has (`Dispose`) it will be called automatically if the object has been wrapped in an `using` block.. – Dykam Aug 28 '10 at 09:39
  • oops, thought this question was tagged C++. With C# you can use `try`/`finally` (of which `using` is a special case) to cause cleanup code to run before return. – Ben Voigt Aug 28 '10 at 14:59
  • This just got a vote which made me look at it for the first time in years. Boy oh boy have my opinions changed on things like this. I now much prefer the early return. – Jean-Bernard Pellerin May 28 '18 at 15:46
3

I prefer the early return - but in general, I really try to avoid switch if at all possible unless it is choosing between at most 3 options. And I try to isolate the switch as much as possible, so that the method with the switch only determines the variable part - everything else is handled by the calling code.

IMO, the early return is easier to read as I don't need to 'read' further when I encounter a return.

Goblin
  • 7,970
  • 3
  • 36
  • 40
  • They tend to build up messes over time when they expand to more than 3 options with a lot of flags (and whistles) and make for hard-to-read code IMO. – Goblin Aug 27 '10 at 22:58
2

This looks like a really elaborate ploy to avoid the && operator. Boolean expressions are coolio:

public bool foo(int param)
{
    return (param == 1) && something;
}
Hans Passant
  • 922,412
  • 146
  • 1,693
  • 2,536
  • 2
    Not to burst your bubble (I think Boolean expressions are cool too :)), but I think he went with a really simple example... – Goblin Aug 27 '10 at 21:45
  • @Goblin: there's bubble hope here :) Falls in the class of if (mumble) return true; else return false; – Hans Passant Aug 27 '10 at 21:55
2

Given the two options, I say neither because they are nesting too far -- you should be calling a function that returns a boolean in your examples.

Given the question between single point of return and multiple point of return (and my previous point), I take the multiple point of return because you can just return the value your function for that case returned.

As an example:

public bool foo(param)
{
    switch (param)
    {
        case 1:
            return MethodForParamEqualOne();
        default:
            throw new ArgumentException("Param value=" + param + " is not supported.");
    }
    //If you're doing stuff here, the method is likely doing too much.
}

Eventually these switch statements get refactored out into method calls off objects (which will improve the terrible nesting switches give you). If you're real savvy, you may not even need the switch statement in your object factory (xml configs, reflection, database, ...).

Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
1

It all depends on what I'm doing. If I do the case and then I'm done, I will return--why execute unnecessary code? If I want to do more work, then I set a flag or something. Use the right tool for the right job.

Muad'Dib
  • 28,542
  • 5
  • 55
  • 68
1

I would remove the switch statement altogether:

public bool foo(param)
{
   if(param != 1)
   {
    throw new ArgumentException("Param value=" + param + " is not supported.");
   }

   return MethodForParamEqualOne();
}
Chuck Conway
  • 16,287
  • 11
  • 58
  • 101
1

When it comes to returns and choice of conditional blocks it may be a good idea to always keep in the back of your head, to comment critical code. If you use

while(true)

don't be afraid to throw a

//WARNING + reason!

on top of the break code. Usually that's overkill most people will tell you , but as soon as it's gets a little bit more dicy with

for (int x = 0; /*external variable for condition*/ ; x ++)

I have found that helped me preventing code wrecking quite often when quickly trying to test small changes in a lot of code you actually don't have to read as much code anymore giving a small time bonus for others.

A bit of a peanut thing to be honest, but I just figure I'd share what has helped me, so it may help others.

bool a = false;

while(true)
{
   ReDraw();
   ReUpdate();       

   //WARNING! Critical breakpoint   <--- Edit , nobody likes a game you can't win :P
   a = CheckForWinGame();
   if (a) 
   { 
      break; 
   }
}

In this example I hope to show that the warning told me now in the blink of an eye, I can meddle with methods, but not with the last. It's not waterproof but it's quick

Proclyon
  • 526
  • 5
  • 12