Returning values to a method from a switch statement

G

Guest

Hi, I need to return a value to a methods call from a switch statement nested
in the method. How can this be done?



int myMethod(int someValue)
{

switch (someValue)
{
case(1):
{
return anotherMethod()
}
case(2):
{
return somethingElse()
}
}

}


When I do this, I get a compile error saying, "not all code paths return a
value". I understand why I'm getting this as I'm not returning a value to the
main method. My question is, how do I return the value from the switch?

Thanks in advance
Ant
 
J

jmcgrew

There's nothing wrong with putting a return statement inside a switch.
The reason you're getting that error is because the method won't return
anything if someValue isn't 1 or 2 - there's a possible code path that
leads straight to the end of the method, skipping both return
statements. (Even if you know someValue will always be 1 or 2, the
compiler doesn't know that.)

You can fix it by returning a default value or throwing an exception
after the switch, or adding a default case to the switch and doing it
there:

switch (someValue)
{
case 1:
return anotherMethod();
case 2:
return somethingElse();
default:
throw new ArgumentException("someValue must be 1 or 2");
}

Jesse
 
K

KJ

You also need a "default:" statement, since there are more possible
values to someValue than 1 and 2 (what happens if someone calls
myMethod(42)?). Also, the curly braces after each case statement are
superflous, as are the parens around 1 and 2.

Have fun.
 
G

Guest

Hi Ant,

As a best practice you should try programming using a single point of exit
within your procedures that way you will never walk into problems like you
are facing right now.
So something like this.

int myMethod(int someValue)
{
int result;
switch (someValue)
{
case(1):
{
result = 12;
}
case(2):
{
result = 13;
}
}
return result;
}


Kind Regards,
 
M

Michael S

This won't work.
You'll get another compile-time error as result may not be initialized...

Happy Coding
- Michael S
 
J

Jon Skeet [C# MVP]

Rainier said:
As a best practice you should try programming using a single point of exit
within your procedures that way you will never walk into problems like you
are facing right now.

No, instead you'll run into problems where the code is much harder to
read because you need much more indentation to cope with the fact that
simple "I'm done now" situations aren't just returned from.

I've read a lot of code which followed the "only return from one place"
mentality, and a lot of it was hellish.

Jon
 
J

Jon Skeet [C# MVP]

Michael said:
This won't work.
You'll get another compile-time error as result may not be initialized...

Which is absolutely equivalent to the original problem, in fact. So the
code has been made more complex without fixing the problem.
Interesting...

Jon
 
R

rich

Plus some fall through errors, but as the compiler catches the problems
with the user error in both methods I don't think that's a reason for
choosing one over the other. Single return can make it easier to avoid
code duplication, but early return for degenerate cases mostly makes
things clearer, as with the typical
public override bool Equals(object obj)
{
if (obj == null || GetType() != obj.GetType())
{
return false;
}
//

It's a pity VS doesn't seem to highlight possible exit points from a
method like some IDEs (maybe I missed it)
 
J

Jim Holmes

It's a pity VS doesn't seem to highlight possible exit points from a
method like some IDEs (maybe I missed it)

CodeRush, a commercial addin for VS, has this among its extensive feature
list.
 
M

Michael S

Jon Skeet said:
No, instead you'll run into problems where the code is much harder to
read because you need much more indentation to cope with the fact that
simple "I'm done now" situations aren't just returned from.

I've read a lot of code which followed the "only return from one place"
mentality, and a lot of it was hellish.

Jon

Agree.

Makes me think of this motto: - Keep it as simple as possible, but no
simpler!
Was it Einstein who said that? Anyone know?

- Michael S
 
B

Bill Butler

Jon Skeet said:
No, instead you'll run into problems where the code is much harder to
read because you need much more indentation to cope with the fact that
simple "I'm done now" situations aren't just returned from.

I've read a lot of code which followed the "only return from one place"
mentality, and a lot of it was hellish.

Careful Jon. The Purity Zealots will come and take you away for such blasphemy.
In a Pre-Exception world it was MUCH more important to follow this logic. That way you have all of
your resource cleanup in one place. Ooops, Only cleaned up the resources in 19 of the exit points
instead of 20.
Of course I often broke the *Rule* even then. When I was *Lucky* enough to inherit one of these
messes, I generally refactored the mess into 2 functions. The outer function handled Setup,Error
handling, and Cleanup. The inner function acted like a Sieve that fell through. This put all of my
error handling in one place and all of my Cleanup in one place.
I had a common point of return from the Outer function and a cleaner flow in the inner function.
So, even though I didn't follow the *Rule*, I did address the issues that the *Rule* was meant to
solve.
Amazingly, once Exceptions are taken into account this *Sieve* logic becomes much more
practical(and common). Of course most of the "return"s are replaced by exceptions, but the concept
is the same.
try/finally for setup/cleanup
try/catch for error handling.

Even though I won't hesitate to use a *Sieve* in my code MOST of my methods follow the "single point
of return" methodology. This mainly comes from a desire to maintain flow control. For instance, if I
want to ensure that ALL code paths (except nasty exceptions) flow through a given point, so I can
put in tracing or something.

In general, if the logic flow doesn't get too convoluted I will use a single point of return,
but I won't lose any sleep over implementing a *Sieve*.

Bill
 
G

Guest

Thanks everyone. Phew!

I ended up just using a default & including an exeption in it. (Whosever
idea that was, thanks). As for single point of exit, I just used the return
of each. It works fine & isn't difficult to read.
Thaks for all your thoughts
Ant
 
J

Jeff Louie

Bill... Single entry, single exit, AKA SESE, seems to work for you and
has kept you out of trouble so go with it, but SESE is no longer a
coding standard in C++. C++ Coding Standards Herb Sutter, Andrei
Alexandrescu page 3. So I am not sure any zealot will complain in C#.

Regards,
Jeff
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top