[Flags] on enum declarations

P

Paul E Collins

The help file says that "bit fields [i.e. enums that have the Flags
attribute] can be combined using a bitwise OR operation, whereas
enumerated constants cannot", and yet this code works:

enum Blah { a, b, c }; // without [Flags]
....
Blah x = Blah.a | Blah.b;

So what is the purpose of the Flags attribute? I understand it's
potentially useful for reflection, so that (for example) the IDE's
IntelliSense knows which enums are meant to be combined, but does it
have no effect on compilation at all - and, if so, is that comment in
the help file incorrect?

P.
 
D

Daniel O'Connell [C# MVP]

Paul E Collins said:
The help file says that "bit fields [i.e. enums that have the Flags
attribute] can be combined using a bitwise OR operation, whereas
enumerated constants cannot", and yet this code works:

enum Blah { a, b, c }; // without [Flags]
...
Blah x = Blah.a | Blah.b;

So what is the purpose of the Flags attribute? I understand it's
potentially useful for reflection, so that (for example) the IDE's
IntelliSense knows which enums are meant to be combined, but does it have
no effect on compilation at all - and, if so, is that comment in the help
file incorrect?

Within C# itself, the Flags attribute is ignored. IDEs, reflection, or other
tools might use it and other languages(or even C# in the future) might
enforce its use or emit warnings if you use bitwise operations on non-flags
enums. Remember, the framework is designed to support multiple languages.
 
R

Richard Blewett [DevelopMentor]

Flags indicates that the enum is intended to be used as a set of bit fields. The ony practical difference it makes is in the implementation of ToString on the enum. without the attribute it simply prints out teh symbolic equivelent of the value or the value uf there is no equiveleint. With teh attribute if it can't find the exact match it tries to oassembly the value from the bitwise orable fields and if successful prints out teh list of fields comma separated.

Regards

Richard Blewett - DevelopMentor
http://www.dotnetconsult.co.uk/weblog
http://www.dotnetconsult.co.uk

The help file says that "bit fields [i.e. enums that have the Flags
attribute] can be combined using a bitwise OR operation, whereas
enumerated constants cannot", and yet this code works:

enum Blah { a, b, c }; // without [Flags]
...
Blah x = Blah.a | Blah.b;

So what is the purpose of the Flags attribute? I understand it's
potentially useful for reflection, so that (for example) the IDE's
IntelliSense knows which enums are meant to be combined, but does it
have no effect on compilation at all - and, if so, is that comment in
the help file incorrect?

P.
 
B

branco.medeiros

Paul said:
The help file says that "bit fields [i.e. enums that have the Flags
attribute] can be combined using a bitwise OR operation, whereas
enumerated constants cannot", and yet this code works:

enum Blah { a, b, c }; // without [Flags]
...
Blah x = Blah.a | Blah.b;
<cut>

Really?

By the rules of the enum type, a, b and c would have the values 0, 1
and 2, respectivelly.

Then

Blah x = Blah.a | Blah.b;

would be x = 0 | 1, which is 1. Sure, if you test later if "a" is set
in x, you'll find that it is:

if ((x & a) == a) { ...

But then, "a" would be set here, also:

Blah y = Blah.b | Blah.c;
if ((y & a) == a) {

In other words, any number & 0 wil always return 0, and it would seem
that the "a" flag would always be set.

Now, if you had

enum Blah { a, b, c, d };

then the value of d would be 3. Now consider this:

Blah z = b | c;
if ((z & d) == d) {//... what gives?!?

Because the bit pattern of d (3 in binary is 11) is the same of OR'ing
together b and c (01 and 10 in binary, respectivelly), it would always
seem that d is set in a Blah var loaded with b and c (and
vice-versa)... Probably not what you'd expect.

It turns out that besides marking an enum with the Flags attribute so
the system considers it a bit mask, you must also choose the values of
the constants carefully, each one representing a specific bit pattern:

enum Blah { a=1, b=2, c=4, d=8, e=16 }; //and so on

Regards,

Branco.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top