Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler error for exhaustive switch

Why do I get a "not all code paths return a value", for VeryBoolToBool() in the following code?

public enum VeryBool { VeryTrue, VeryFalse };
public bool VeryBoolToBool(VeryBool veryBool)
{
    switch(veryBool)
    {
        case VeryBool.VeryTrue:
            return true;

        case VeryBool.VeryFalse:
            return false;

        // Un-commenting the unreachable(?) default clause will solve this
        // default:
        //    throw new HowTheHellDidIGetHereException();
    }
}

Can't the compiler see there are no other options for VeryBool?

like image 606
bavaza Avatar asked Dec 24 '13 10:12

bavaza


1 Answers

Can't the compiler see there are no other options for VeryBool?

Nope, because there are. For example, I could call:

VeryBoolToBool((VeryBool) 5);

Enums in C# are not limited sets of values. They're effectively named numbers, with additional compile-time type safety in that there aren't implicit conversions between enums or between enums and numbers. (There are explicit conversions though.) The explicit conversions do not ensure that the value in question is one with a name, however.

Beyond that, switch in C# never checks whether all possible values of the type are explicitly listed. The end of a switch statement is always deemed "reachable" unless there's a default case (and all cases terminate). More precisely, from the end of section 8.7.2 of the C# 5 specification:

The end point of a switch statement is reachable if at least one of the following is true:

  • The switch statement contains a reachable break statement that exits the switch statement.
  • The switch statement is reachable, the switch expression is a non-constant value, and no default label is present.
  • The switch statement is reachable, the switch expression is a constant value that doesn’t match any case label, and no default label is present.
like image 178
Jon Skeet Avatar answered Oct 11 '22 14:10

Jon Skeet