Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch + Enum = Not all code paths return a value

Tags:

c#

I'm just curious why this code...

    enum Tile { Empty, White, Black };
    private string TileToString(Tile t)
    {
        switch (t)
        {
            case Tile.Empty:
                return ".";
            case Tile.White:
                return "W";
            case Tile.Black:
                return "B";
        }
    }

Throws that error. It's not possible for t to take on any other value, is it? Shouldn't the compiler be clever enough to figure that out?

like image 385
mpen Avatar asked Sep 02 '10 08:09

mpen


2 Answers

No, you can use any int value converted to Tile. Try this:

Tile t = (Tile) 5;
string s = TileToString(t);

An enum is a set of names for numbers, effectively... but neither the compiler nor the CLR enforces that a value of the enum type has a name. It's a pain, but there it is...

I would suggest a default case which threw ArgumentException (or possibly ArgumentOutOfRangeException).

like image 65
Jon Skeet Avatar answered Oct 05 '22 06:10

Jon Skeet


Jon is of course entirely correct that an enum can have any value of its underlying type, and therefore the switch is not exhaustive, and therefore there is a code path that does not return. However, that is not a complete analysis of the issue. Even if it were the case that the switch was exhaustive, you'd still get the error.

Try it:

int M(bool b) 
{
    switch(b)
    {
        case true : return 123;
        case false: return 456;
    } 
}

Or

int M(byte b) 
{
    switch(b)
    {
        case 0: case 1: case 2: ... all of them ... case 255: return 123;
    } 
}

In both these cases you'll get the same "reachable end point in non-void method" error.

This is simply an oversight in the "reachability checking" section of the C# specification. We define the end point of a switch statement as being reachable if it doesn't have a default section, period. There is no special dispensation for switches that exhaustively consume every possible value of their input. It's a corner case that the language designers missed, and it's never been nearly a high enough priority to fix it.

For three other interesting facts about analysis of switch statements, see:

http://ericlippert.com/2009/08/13/four-switch-oddities/

like image 20
Eric Lippert Avatar answered Oct 05 '22 07:10

Eric Lippert