Why do [Flag] 's enumerations start at 0 and increase by 1?

Edit: It seems most people misunderstood my question.

I know how enum works, and I know the binary. I wonder why enumerations with the [Flags] attribute are designed as they are.

Original post:

It may be a duplicate, but I did not find any other posts, so here it goes.

I am sure there was a good justification behind this, I just find it a little error prone.

[Flag] public enum Flagged { One, // 0 Two, // 1 Three, // 2 Four, // 3 } Flagged f; // Defaults to Flagged.One = 0 f = Flagged.Four; (f & Flagged.One) != 0; // Sure.. One defaults to 0 (f & Flagged.Two) != 0; // 3 & 1 == 1 (f & Flagged.Three) != 0; // 3 & 2 == 2 

Wouldn't that make sense if he did something like this?

 [Flag] public enum Flagged { One = 1 << 0, // 1 Two = 1 << 1, // 2 Three = 1 << 2, // 4 Four = 1 << 3, // 8 } Flagged f; // Defaults to 0 f = Flagged.Four; (f & Flagged.One) != 0; // 8 & 1 == 0 (f & Flagged.Two) != 0; // 8 & 2 == 0 (f & Flagged.Three) != 0; // 8 & 4 == 0 (f & Flagged.Four) != 0; // 8 & 8 == 8 

Of course. I'm not quite sure how it should handle user flags like

 [Flag] public enum Flagged { One, // 1 Two, // 2 LessThanThree = One | Two, Three, // 4? start from Two? LessThanFour = Three | LessThanThree, Three, // 8? start from Three? } 

The specification gives some recommendations.

Define the enumeration constants by the powers of two, i.e. 1, 2, 4, 8, etc. This means that individual flags in combined enumeration constants do not overlap.

But this should be done automatically, as I bet you will never want my first example to happen. Please enlighten me :)

+6
enums c # bitflags
source share
6 answers

The [Flags] attribute is not [Flag], and there is nothing magical about it. The only thing that seems to affect the ToString method. When [Flags] is specified, values ​​are displayed with a comma. You need to specify the values ​​to make them valid for use in the bit field.

+6
source share

The Flags attribute is used only to format values ​​as multiple values. Bit operations work with a base type with or without an attribute.

+12
source share

The first element of the enumeration is zero unless another value is explicitly specified. It is often best to have a null value for flag enumerations, as it gives semantic meaning to a null value such as No Flags or Disabled. This can be useful when saving code, as it may mean the intent of your code (although comments also achieve this).

Other than that, you really need your design as well, whether you need a zero value or not.

Since flag enumerations are still just enumerations ( FlagsAttribute simply instructs the debugger to interpret the values ​​as combinations of other values), the next value in the enumeration will always be greater than the previous value. Therefore, you must specify the bit values ​​explicitly, as you can express combinations as bitwise OR other values.

However, it is unreasonable to present a syntax for flag enumerations that requires all bitwise combinations to be placed at the end of the enumeration definition or somehow labeled so that the compiler knows how to handle everything else.

For example (assuming the flags keyword and that we are in the northern hemisphere),

 flags enum MyFlags { January, February, March, April, May, June, July, August, September, October, November, December, Winter = January | February | March Spring = April | May | June Summer = July | August | September Autumn = October | November | December } 

Using this syntax, the compiler can create the value 0 itself and automatically assign flags to other values.

+7
source share

There is nothing in the annotated C # 3 specification. I think there might be something in the annotated C # 4 spec - I'm not sure. (I think that I myself began to write such an annotation, but then deleted it.)

This is good for simple cases, but as soon as you start adding extra flags, it gets a little trickier:

 [Flags] enum Features { Frobbing, // 1 Blogging, // 2 Widgeting, // 4 BloggingAndWidgeting = Frobbing | Blogging, // 6 Mindnumbing // ? } 

What is the meaning of Mindnumbing? The next bit that is not used? What if you set a fixed integer value?

I agree that this is a pain. Maybe some rules can be developed, which would be reasonable ... but I wonder if complexity and balance of value will really look.

+4
source share

Simply put, Flags is an attribute. It does not apply until an enumeration is created and thus does not change the values ​​assigned to the enumeration.

Having said that, the MSDN Design for Flag Enumerations page says the following:

Use permissions for two enumeration flags so that they can be freely combined using a bitwise OR operation.

Important: if you do not use powers of two or a combination of powers of two, bitwise operations will not work properly.

Similarly, the FlagsAttribute page says

Define enumeration constants in powers of two, i.e. 1, 2, 4, 8, etc. on. This means that individual flags combined enumeration constants are not overlapping.

+2
source share

In C, you can (ab) use a preprocessor to automatically generate multiplications with two parameters. If you have a make_things macro that expands to "make_thing (flag1) make_thing (flag2) make_thing (flag3)" etc., you can call this macro several times, with different make_thing definitions, to achieve power in two sequence of flag names as well as some other goodies.

For example, run the definition of make_thing (x) as "LINEAR_ENUM _ ## x" (including a comma), and then use the enumeration operator to create a list of enumerations (including outside the make_things macro, LINEAR_NUM_ITEMS). Then create another enum, this time with make_thing (x) defined as "FLAG_ENUM _ ## x = 1 <

Most likely, some of the things that can be done this way, with a flag and linear values ​​that are automatically stored in synchronization; the code can do nice things like "if (thingie [LINEAR_ENUM_foo] thing_errors | = FLAG_ENUM_foo;" (using both linear and flag values). Unfortunately, I don't know how to do something like this remotely in C # or VB.net.

0
source share

All Articles