To allow a single enum instance to represent multiple values (usually referred to as flags), one can annotate the enum with the [Flags]
attribute. By carefully assigning the values of the enum members such that specific bits are set to 1
, bitwise operators can be used to set or unset flags.
[Flags]
enum PhoneFeatures
{
Call = 1,
Text = 2
}
Besides using regular integers to set the flag enum members' values, one can also use binary literals or the bitwise shift operator.
[Flags]
enum PhoneFeaturesBinary
{
Call = 0b00000001,
Text = 0b00000010
}
[Flags]
enum PhoneFeaturesBitwiseShift
{
Call = 1 << 0,
Text = 1 << 1
}
An enum member's value can refer to other enum members values:
[Flags]
enum PhoneFeatures
{
Call = 0b00000001,
Text = 0b00000010,
All = Call | Text
}
Setting a flag can be done through the bitwise OR operator (|
) and unsetting a flag through a combination of the bitwise AND operator (&
) and the bitwise complement operator (~
). While checking for a flag can be done through the bitwise AND operator, one can also use the enum's HasFlag()
method.
var features = PhoneFeatures.Call;
// Set the Text flag
features = features | PhoneFeatures.Text;
features.HasFlag(PhoneFeatures.Call); // => true
features.HasFlag(PhoneFeatures.Text); // => true
// Unset the Call flag
features = features & ~PhoneFeatures.Call;
features.HasFlag(PhoneFeatures.Call); // => false
features.HasFlag(PhoneFeatures.Text); // => true
The working with enums as bit flags tutorial goes into more detail how to work with flag enums. Another great resource is the [enum flags and bitwise operators page][alanzucconi.com-enum-flags-and-bitwise-operators].
By default, the int
type is used for enum member values. One can use a different integer type by specifying the type in the enum declaration:
[Flags]
enum PhoneFeatures : byte
{
Call = 0b00000001,
Text = 0b00000010
}