tl;dr- Yes, it's generally proper to throw an exception whenever the code attempts to do something that it wasn't designed for, including unexpected defaulting in a switch.
Scenario 1: Dense logic, where all cases ought to be handled properly.
It's pretty common to switch
on an enum
.
For example, I'd often have code like this:
public enum Things
{
A,
B,
C
}
public void HandleThing(Things thing)
{
switch (thing)
{
case Things.A: { HandleA(); return; }
case Things.B: { HandleB(); return; }
case Things.C: { HandleC(); return; }
default: { throw new NotImplementedException(); }
}
}
Since the enum
's cases are all accounted for, the default
branch shouldn't be possible. So, ideally, this method can't throw an exception.
I always include the throw
anyway as future-proofing. I figure:
If the enum
never changes, then it's all good.
If the enum
does change and the switch
is updated to handle the new case, then it's all good.
If the enum
does change but the switch
isn't updated, then throwing an exception is appropriate.
Scenario 2: Sparse logic, where cases are handled opportunistically.
By contrast, say that you have a switch
that doesn't necessarily need to perform any work, but rather does something opportunistic.
For example, sometimes in computationally expensive software, e.g. mathematical simulations, you might look for special cases that can be handled more cheaply. If you don't catch a special case, then the more expensive general method will be used instead – which may be slower, but it shouldn't cause the software to malfunction.
In such opportunistic cases, you may want the default
to not throw.
That said, you might still include information-logging in an #if DEBUG
/#endif
pre-processor directive block to record that an unexpected opportunity was missed at design-time. If you do this, you'd probably want to include explicit case
-branches for cases that you're aware of but don't want to react to, to avoid falsely triggering the default
-branch.
I consider than using a switch/case with a string that can take any value is not the best solution but sometime, considering time and development, this is the best dirty way to achieve his goal quickly
You do realize that using an enum can be implemented in less than a minute here, right? On top of that, if you use Tab-generation for your switch statement, when using an enum it autogenerates cases for all known enum values, so you're saving more time than it takes to implement the enum.