DekGenius.com
[ Team LiB ] Previous Section Next Section

Recipe 4.4 Testing for a Valid Enumeration of Flags

Problem

You need to determine whether a given value is a valid enumeration value or a valid combination of enumeration values (i.e., bit flags ORed together in an enumeration marked with the Flags attribute).

Solution

There is a problem with using Enum.IsDefined with an enumeration marked with the Flags attribute. Consider the situation if the Language enumeration were written as follows:

[Flags]
enum Language
{
    CSharp = 1, VBNET = 2, VB6 = 4
}

Valid values for Language include the set of numbers {1, 2, 3, 4, 5, 6, 7}; however, the values 3, 5, 6, and 7 are not explicitly represented in this enumeration. The value 3 is equal to the CSharp and VBNET enumeration members ORed together and the value 7 is equal to all of the enumeration members ORed together. This means that for the values 3, 5, 6, and 7, the Enum.IsDefined method will return false, indicating that these are not valid values, when, in fact, they are. We need a way to determine whether a correct set of flags has been passed into a method.

To fix this problem, we can add a new member to the Language enumeration to define all values for which the Language enumeration is valid. In our case, the Language enumeration would be rewritten as:

[Flags]
enum Language
{
    CSharp = 1, VBNET = 2, VB6 = 4, 
    All = (CSharp | VBNET | VB6)
}

The new All enumeration member is equal to all other Language members ORed together. Now, when we want to validate a Language flag, all we have to do is the following:

public bool HandleFlagsEnum(Language language)
{
    if ((language & Language.All) == language)
    {
        return (true);
    }
    else
    {
        return (false);
    }
}

Discussion

If you want to use the HandleFlagsEnum method with existing code, all that is required is to add an All member to the existing enumeration. The All member should be equal to all the members of the enumeration ORed together.

The HandleFlagsEnum method then uses this All member to determine whether an enumeration value is valid. This is accomplished by ANDing the language value with the Language.All value in the HandleFlagsEnum method.

This method can also be overloaded to handle the underlying type of the enumeration as well (in this case, the underlying type of the Language enumeration is an integer). The following code determines whether an integer variable contains a valid Language enumeration value:

public static bool HandleFlagsEnum(int language)
{
    if ((language & (int)Language.All) == language)
    {
        return (true);
    }
    else
    {
        return (false);
    }
}

The overloaded HandleFlagsEnum methods return true if the language parameter is valid, and false otherwise.

See Also

To test for a valid enumeration within an enumeration not marked with the [Flags] attribute, see Recipe 4.3.

    [ Team LiB ] Previous Section Next Section