Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the [Flags] Enum Attribute mean in C#?

Tags:

c#

enums

flags

From time to time I see an enum like the following:

[Flags] public enum Options  {     None    = 0,     Option1 = 1,     Option2 = 2,     Option3 = 4,     Option4 = 8 } 

I don't understand what exactly the [Flags] attribute does.

Anyone have a good explanation or example they could post?

like image 456
Brian Leahy Avatar asked Aug 12 '08 04:08

Brian Leahy


People also ask

What are flags in enum?

Flags, enum. Flags allow an enum value to contain many values. An enum type with the [Flags] attribute can have multiple constant values assigned to it. With Flags, it is still possible to test enums in switches and if-statements. Flags can be removed or added. We can specify multiple flags with the "or" operator.

What is the role of Flag attribute in enum?

The [Flag] attribute is used when Enum represents a collection of multiple possible values rather than a single value. All the possible combination of values will come. The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value.

What is an enum attribute?

Definition. An Enumeration (or enum ) is a data type that includes a set of named values called elements or members. The enumerator names are usually identifiers that behave as constants in the language.

What is the use of Flag in C sharp?

Flag variable is used as a signal in programming to let the program know that a certain condition has met. It usually acts as a boolean variable indicating a condition to be either true or false.


2 Answers

The [Flags] attribute should be used whenever the enumerable represents a collection of possible values, rather than a single value. Such collections are often used with bitwise operators, for example:

var allowedColors = MyColor.Red | MyColor.Green | MyColor.Blue; 

Note that the [Flags] attribute doesn't enable this by itself - all it does is allow a nice representation by the .ToString() method:

enum Suits { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 } [Flags] enum SuitsFlags { Spades = 1, Clubs = 2, Diamonds = 4, Hearts = 8 }  ...  var str1 = (Suits.Spades | Suits.Diamonds).ToString();            // "5" var str2 = (SuitsFlags.Spades | SuitsFlags.Diamonds).ToString();            // "Spades, Diamonds" 

It is also important to note that [Flags] does not automatically make the enum values powers of two. If you omit the numeric values, the enum will not work as one might expect in bitwise operations, because by default the values start with 0 and increment.

Incorrect declaration:

[Flags] public enum MyColors {     Yellow,  // 0     Green,   // 1     Red,     // 2     Blue     // 3 } 

The values, if declared this way, will be Yellow = 0, Green = 1, Red = 2, Blue = 3. This will render it useless as flags.

Here's an example of a correct declaration:

[Flags] public enum MyColors {     Yellow = 1,     Green = 2,     Red = 4,     Blue = 8 } 

To retrieve the distinct values in your property, one can do this:

if (myProperties.AllowedColors.HasFlag(MyColor.Yellow)) {     // Yellow is allowed... } 

or prior to .NET 4:

if((myProperties.AllowedColors & MyColor.Yellow) == MyColor.Yellow) {     // Yellow is allowed... }  if((myProperties.AllowedColors & MyColor.Green) == MyColor.Green) {     // Green is allowed... }     

Under the covers

This works because you used powers of two in your enumeration. Under the covers, your enumeration values look like this in binary ones and zeros:

 Yellow: 00000001  Green:  00000010  Red:    00000100  Blue:   00001000 

Similarly, after you've set your property AllowedColors to Red, Green and Blue using the binary bitwise OR | operator, AllowedColors looks like this:

myProperties.AllowedColors: 00001110 

So when you retrieve the value you are actually performing bitwise AND & on the values:

myProperties.AllowedColors: 00001110              MyColor.Green: 00000010              -----------------------                             00000010 // Hey, this is the same as MyColor.Green! 

The None = 0 value

And regarding the use of 0 in your enumeration, quoting from MSDN:

[Flags] public enum MyColors {     None = 0,     .... } 

Use None as the name of the flag enumerated constant whose value is zero. You cannot use the None enumerated constant in a bitwise AND operation to test for a flag because the result is always zero. However, you can perform a logical, not a bitwise, comparison between the numeric value and the None enumerated constant to determine whether any bits in the numeric value are set.

You can find more info about the flags attribute and its usage at msdn and designing flags at msdn

like image 176
andynil Avatar answered Sep 30 '22 21:09

andynil


You can also do this

[Flags] public enum MyEnum {     None   = 0,     First  = 1 << 0,     Second = 1 << 1,     Third  = 1 << 2,     Fourth = 1 << 3 } 

I find the bit-shifting easier than typing 4,8,16,32 and so on. It has no impact on your code because it's all done at compile time

like image 27
Orion Edwards Avatar answered Sep 30 '22 22:09

Orion Edwards