You need to determine
whether a given value is a valid enumeration value or a valid
combination of enumeration values (i.e., bit flags
OR
ed together in an enumeration marked with the
Flags
attribute).
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 OR
ed together and the value
7
is equal to all of the enumeration members
OR
ed 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 OR
ed
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); } }
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 OR
ed
together.
The HandleFlagsEnum
method then uses this
All
member to determine whether an enumeration
value is valid. This is accomplished by AND
ing 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.
To test for a valid enumeration within an enumeration not marked with
the [Flags]
attribute, see Recipe 4.3.