Validate a switch statement that uses values from an enumerated type in C#

Enumerated types and switch statements often go hand-in-hand. You define an enumerated type and then later use a switch statement to see which of the values is contained in some variable.

This can lead to a fairly common bug when you change the enum values. If you add a new enum value, the switch statement may not handle it properly. If the switch statement contains a default case, then the code will continue to run even though it may not handle the new case correctly, and you may not notice that there's a problem until much later when it is harder to debug.

To prevent this kind of problem, list every enum value explicitly in the switch statement. Then add a default case that uses Debug.Assert to point out the problem. When you're testing the program and the assertion fails, you can easily add a new case statement to handle the new value.

If the program can meaningfully handle the new value, you can also add code to treat the new value as benignly as possible in the default case.

The following code shows how this example protects a switch statement.

// The list of user types.
private enum UserTypes
{
SalesAndShippingClerk,
ShiftSupervisor,
StoreManager,
VicePresident
}

// Get the selected user type.
private void cboUserType_SelectedIndexChanged(object sender, EventArgs e)
{
// Convert the ComboBox's text into the Pascal cased name.
string type_name = cboUserType.Text.ToPascalCase();

// Convert the name into a UserTypes value.
UserTypes user_type = (UserTypes)Enum.Parse(typeof(UserTypes), type_name);

// Prove it worked.
switch (user_type)
{
case UserTypes.SalesAndShippingClerk:
lblSelectedType.Text = "You selected sales && shipping clerk.";
break;
case UserTypes.ShiftSupervisor:
lblSelectedType.Text = "You selected shift supervisor.";
break;
case UserTypes.StoreManager:
lblSelectedType.Text = "You selected store manager.";
break;
default:
// Tell the developer there's a problem.
Debug.Assert(false, "Unhandled UserTypes value " + user_type.ToString());

// Use the safest user type.
lblSelectedType.Text = "";
user_type = UserTypes.SalesAndShippingClerk;
break;
}
}

This switch statement is designed to handle the UserTypes values SalesAndShippingClerk, ShiftSupervisor, and StoreManager, but I modified the enum to include a new VicePresident value. If you select the Vice President value from the ComboBox, you'll see the assertion.

Note that you still need to execute the switch statement with the new value before you'll see the problem so this technique doesn't eliminate the need for thorough testing. It just makes it easier to detect an error during testing when it otherwise might slip by unnoticed.

See also:

   

 

What did you think of this article?




Trackbacks
  • No trackbacks exist for this post.
Comments
  • No comments exist for this post.
Leave a comment

Submitted comments are subject to moderation before being displayed.

 Name

 Email (will not be published)

 Website

Your comment is 0 characters limited to 3000 characters.