The "problem" you refer is intrinsic to switch...case and thus the best thing you can do to avoid it is relying on a different alternative. I personally don't like too much switch...case because of its inflexibility. Thus, this answer intends to provide an alternative to switch statements capable to deliver the kind of zero-uncertainty you are looking for.
In this kind of situations, I usually rely on a set of conditions taken from an array populated at the start of the function which will automatically filter any unaccounted input. Example:
private void DoStuffMyWay(StuffToDo stuff)
{
StuffToDo[] accountedStuff = new StuffToDo[] { StuffToDo.Bike, StuffToDo.Run, StuffToDo.Swim };
if (accountedStuff.Contains(stuff))
{
if (stuff == accountedStuff[0])
{
//do bike stuff
}
else if (stuff == accountedStuff[1])
{
//do run stuff
}
else if (stuff == accountedStuff[2])
{
//do swim stuff
}
}
}
This is certainly not too elegant, but I guess that I am not an elegant programmer.
As far as perhaps you prefer a different type of approach to the problem, here you have another alternative; it is less efficient but looks nicer:
private void DoStuffWithStyle(StuffToDo stuff)
{
Dictionary<StuffToDo, Action> accountedStuff = new Dictionary<StuffToDo, Action>();
accountedStuff.Add(StuffToDo.Bike, actionBike);
accountedStuff.Add(StuffToDo.Run, actionRun);
accountedStuff.Add(StuffToDo.Swim, actionSwim);
if (accountedStuff.ContainsKey(stuff))
{
accountedStuff[stuff].Invoke();
}
}
private void actionBike()
{
//do bike stuff
}
private void actionRun()
{
//do run stuff
}
private void actionSwim()
{
//do swim stuff
}
With this second option, you might even create the dictionary as a global variable and populate it together with the enum.