7

I understand how Enums work in C#, and I get what the Flags attribute brings to the table.

I saw this question, here. Which recommends the first flavor, but doesn't provide any reason/justification for it.

Is there a difference in the way in which these two are defined, is one better than the other? What are the advantages to using the first synax as instead of the second? I've always used the second flavor when defining Flags type Enums... have I been doing it wrong all this time?

[Serializable]
[Flags]
public enum SiteRoles
{
    User = 1 << 0,
    Admin = 1 << 1,
    Helpdesk = 1 << 2
}

Is that not the same as

[Serializable]
[Flags]
public enum SiteRoles
{
    User = 1,
    Admin = 2,
    Helpdesk = 4
}
3
  • The IL code produced for these 2 code fragmens is the same. Commented Jan 25, 2010 at 17:36
  • 3
    Spot the bug in this code: BackupOperator = 1073714824. You can avoid the bug in the first place by saying BackupOperator = 1<<30 Commented Jan 25, 2010 at 18:53
  • Thanks for the info all, I'll be using the first aproach, since it seems better for all but the most simple cases. Commented Jan 26, 2010 at 14:09

3 Answers 3

6

The main advantage with the first one is that you don't need to calculate the correct values for each flag since the compiler will do it for you. Apart from that they are the same.

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, 1<<n is a constant so the compiler should calculate it which could be less error prone than 1,2,4,8...You could also use hex e.g. 0x1, 0x10, 0x100...
Though you might be more interested in hex values like 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80.
6

Consider more complex samples:

[Flags]
public enum SiteRoles
{
    User = 1 << 12,
    Admin = 1 << 13,
    Helpdesk = 1 << 15,
    AdvancedUser = User | Helpdesk, //or (1<<12)|(1<<13)
}

[Flags]
public enum SiteRoles
{
    User = 4096, //not so obvious!
    Admin = 8192,
    Helpdesk = 16384,
    AdvancedUser = 12288, //!
}

[Flags]
public enum SiteRoles
{
    User = 0x1000, //we can use hexademical digits
    Admin = 0x2000,
    Helpdesk = 0x4000,
    AdvancedUser = 0x3000, //it much simpler calculate binary operator OR with hexademicals
}

This samples shows that in this case first version is MUCH MORE readable. Decimal literals is not the best way to represent flag constants. And for more information about bitwise operations (that also can be used to represent flag constants) see http://en.wikipedia.org/wiki/Bitwise_operation

Comments

0

AFAIK its a readability debate. Some would say the first is more readable because you have the actual index of the flag on the right hand side of the '<<'.

2 Comments

It's not a compiler trick. What's the difference between Helpdesk = 1<<2, Helpdesk = 4 or Helpdesk = 3 + 1. It's just an expression that is evaluated.
I guess I see that as taking advantage of the compiler, and thus a compiler trick. Your point is well taken.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.