views:

152

answers:

6

I have the following code:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
    }
}

public enum MyEnum
{
    Value1,
    Value2,
    Value3
}

And I get the error: "Not all code paths return a value". I do not understand how that switch statement could ever not jump to one of the specified cases.

Can an enum somehow be null?

+2  A: 

If you change the values in your enum (adding a fourth) your code will break. You should add a default: case to your switch statement.

of course, the other way to achieve this would be to define the integer values in your enum...

public enum MyEnum
{
    Value1 = 1,
    Value2 = 2,
    Value3 = 3
}

and then cast your enum as an int in code. Instead of int myInt = Method(myEnumValue); you can use int myInt = (int)myEnum

ZombieSheep
Thats not quite correct, see the other answers.
NickLarsen
The fact that my code breaks if I change it is not the compilers business right?
Matthijs Wessels
Not directly, no, but if you extend my answer with the others listed below you'll see the issue. Bottom line -> add a default case to the code.
ZombieSheep
+12  A: 

There's nothing to say that the value of myEnum will be one of those values.

Don't mistake enums for being a restrictive set of values. It's really just a named set of values. For example, I could call your method with:

int x = Method((MyEnum) 127);

What would you want that to do? If you want it to throw an exception you can do that in a default case:

switch (myEnum)
{
    case MyEnum.Value1: return 1;
    case MyEnum.Value2: return 2;
    case MyEnum.Value3: return 3;
    default: throw new ArgumentOutOfRangeException();
}

Alternatively you could use Enum.IsDefined upfront, if you want to do some other work before the switch statement. That has the disadvantage of boxing... there are some ways round that, but they're generally more work...

Jon Skeet
Aha.... That explains a lot. I'm used to Java enums.
Matthijs Wessels
+4  A: 

Enums are not limited to values they represent. You can assign this:

MyEnum v = (MyEnum)1000;

And there would be no problem at all. Add a default to your switch and you'll handle all possible situations.

NickLarsen
A: 

It has to be either:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
        default: return 0;
    }
}

or:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
    }

    return 0;
}
herzmeister der welten
or you can throw an exception in the case that the Enum is not a valid value, or any other handling case he desires.
NickLarsen
A: 
MyEnum blah = 0;

Default is always 0 and is implicitly convertible, even if you do not have one with a 0 value.

leppie
+1  A: 

You are missing the default case:

public int Method(MyEnum myEnum)
{
    switch (myEnum)
    {
        case MyEnum.Value1: return 1;
        case MyEnum.Value2: return 2;
        case MyEnum.Value3: return 3;
        default: return 0; // Or whatever
    }
}
Laurent Etiemble