Tan Jia Ming
Tan Jia Ming

Reputation: 465

What happens if we declare [Flags] enum in order?

I have came across this question: What does the [Flags] Enum Attribute mean in C#?

And one thing I have been wondering, using the accepted answer's example, what will happen if I declare:

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

Will the following steps in that example resulting an error? If no, how can I get to MyColors.Red?

Upvotes: 5

Views: 1093

Answers (5)

Shahar Prish
Shahar Prish

Reputation: 4849

All the [Flags] attribute does is allow you to apply bitwise operators to the enum.

[Edit is correct - there's not even a warning if you don't specify [Flags] - I could have sworn it used to be like this...]

The =3 (Red) you have there is very useful because you can define combinations to check for... In your example:

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

Now, obviously this is a stupid example, but consider the following:

[Flags]
public enum MyStuff
{
    HasCar = 1,
    HasDog = 2,
    HasKids = 4,
    HasEverything = 7,
}

Now, to check if a variable has everything, you can do the following:

return (myStuff & MyStuff.HasEverything) == MyStuff.HasEverything;

Upvotes: 1

Sriram Sakthivel
Sriram Sakthivel

Reputation: 73462

It will result in unexpected results. Common practice to make uniqueness is just to mark enum values with power of 2.

For instance Yellow bitwise or Green will result in Red and so on.

MyColors colors = MyColors.Yellow | MyColors.Green;
if (colors == MyColors.Red)
{
    Console.WriteLine("Oops!")
}

Also note Flags attribute does nothing here, it gives the impression that you can use bitwise or.

Upvotes: 1

Avner Shahar-Kashtan
Avner Shahar-Kashtan

Reputation: 14700

To elaborate of jdphenix's answer, remember that the [Flags] attribute doesn't actually do any magic. It just adds a purely cosmetic marker on the enum that lets other functions (by default, only an enum's ToString implementation) to treat the enum as a Flags enum.

Regardless of the attribute, an enum is still just a number, by default an Int32, with some syntactic sugar around it. So if you define your enum as you did, doing

MyColors newColor = MyColors.Yellow | MyColors.Green 

would just do a bitwise OR operation on 1 and 2. The magic that is bitwise enums isn't in the attribute, but in the fact that powers of 2 allows you to "switch" a certain bit on and off. Using ordinal numbers will switch off bits that are a part of the binary representation of more than one enum value, making the result of the bitwise operation meaningless.

Upvotes: 3

jmcilhinney
jmcilhinney

Reputation: 54417

The Flags attribute doesn't actually do anything to enum itself or affect how it's used in code. The one and only thing that the Flags attribute does affect is the output of the ToString method. The other purpose of the Flags attribute is to indicate to the developer how they should use the enum. Your example will not cause any error; it's just stupid code. The rules are very simple:

  1. If only one value is supposed to be used at a time then don't apply the Flags attribute and use a singular name for the type.
  2. If multiple values can be used together then apply the Flags attribute, use powers of 2 for the values and use a plural name for the type.

Upvotes: 10

jdphenix
jdphenix

Reputation: 15425

It will not behave as expected. You must use powers of 2 for the declared values of each enum constant. Here is the example directly from the answer you linked:

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

Without the declared values being powers of 2:

  • You will not be able to perform meaningful bitwise operations.
  • You will be able to use it for a normal enum (there will be no compiler error).

Upvotes: 1

Related Questions