Reputation: 11047
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
?
Upvotes: 18
Views: 4608
Reputation: 304
Since C# 8 you can use a switch expression to solve this:
public enum VeryBool { VeryTrue, VeryFalse };
public bool VeryBoolToBool(VeryBool veryBool)
{
return veryBool switch
{
VeryBool.VeryTrue => true,
VeryBool.VeryFalse => false
};
}
Note that you will get a warning:
The switch expression does not handle some values of its input type (it is not exhaustive) involving an unnamed enum value. For example, the pattern '(Fruit)2' is not covered.
But the warning can be suppressed or configured in your editor config (CS8524).
You can still pass an invalid enum value:
VeryBoolToBool((VeryBool) 5);
But this will throw a SwitchExpressionException.
Upvotes: 3
Reputation: 1500495
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.
Upvotes: 20