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

Validate a switch statement

This example shows how you can validate a switch statement that uses values defined in an enumerated type. 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 won’t look for the new case. Often you won’t notice that there’s a problem until much later when it you’ve forgotten the change and debugging the program is much harder.

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 tell you if you’ve missed a case. 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 value VicePresident. 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:


Download Example   Follow me on Twitter   RSS feed   Donate




This entry was posted in debugging and tagged , , , , , , , , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published. Required fields are marked *