Why does [Flag]'d enums start at 0 and increment by 1? - c#

Edit: It seems most people misunderstood my question.
I know how enum works, and I know binary. I'm wondering why the enums with the [Flags] attribute is designed the way it is.
Original post:
This might be a duplicate, but I didn't find any other posts, so here goes.
I bet there has been some good rationale behind it, I just find it a bit bug 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 it have made more sense if it 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 custom flags like this
[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 spec gives some guidelines
Define enumeration constants in powers of two, that is, 1, 2, 4, 8, and so on. This means the individual flags in combined enumeration constants do not overlap.
But this should perhaps be done automatically as I bet you would never want my first example to occur. Please enlighten me :)

The Flags attribute is only used for formatting the values as multiple values. The bit operations work on the underlying type with or without the attribute.

The first item of an enumeration is zero unless explicitly given some other value. It is often best practice to have a zero value for flags enumerations as it provides a semantic meaning to the zero value such as "No flags" or "Turned off". This can be helpful in maintaining code as it can imply intent in your code (although comments also achieve this).
Other than that, it really is up to you and your design as to whether you require a zero value or not.
As flag enumerations are still just enumerations (the FlagsAttribute merely instructs the debugger to interpret the values as combinations of other values), the next value in an enumeration is always one more than the previous value. Therefore, you should be explicit in specifying the bit values as you may want to express combinations as bitwise-ORs of other values.
That said, it is not unreasonable to imagine a syntax for flags enumerations that demands all bitwise combinations are placed at the end of the enumeration definition or are marked in some way, so that the compiler knows how to handle everything else.
For example (assuming a flags keyword and that we're 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
}
With this syntax, the compiler could create the 0 value itself, and assign flags to the other values automatically.

The attribute is [Flags] not [Flag] and there's nothing magical about it. The only thing it seems to affect is the ToString method. When [Flags] is specified, the values come out comma delimited. It's up to you to specify the values to make it valid to be used in a bit field.

There's nothing in the annotated C# 3 spec. I think there may be something in the annotated C# 4 spec - I'm not sure. (I think I started writing such an annotation myself, but then deleted it.)
It's fine for simple cases, but as soon as you start adding extra flags, it gets a bit tricky:
[Flags]
enum Features
{
Frobbing, // 1
Blogging, // 2
Widgeting, // 4
BloggingAndWidgeting = Frobbing | Blogging, // 6
Mindnumbing // ?
}
What value should Mindnumbing have? The next bit that isn't used? What about if you set a fixed integer value?
I agree that this is a pain. Maybe some rules could be worked out that would be reasonable... but I wonder whether the complexity vs value balance would really work out.

Simply put, Flags is an attribute. It doesn't apply until after the enumeration is created, and thus doesn't change the values assigned to the enumeration.
Having said that, the MSDN page Designing Flags Enumerations says this:
Do use powers of two for a flags
enumeration's values so they can be
freely combined using the bitwise OR
operation.
Important: If you do not use powers of two or
combinations of powers of two, bitwise
operations will not work as expected.
Likewise, the page for the FlagsAttribute says
Define enumeration constants in powers
of two, that is, 1, 2, 4, 8, and so
on. This means the individual flags in
combined enumeration constants do not
overlap.

In C, it's possible to (ab)use the preprocessor to generate power-of-two enumerations automatically. If one has a macro make_things which expands to "make_thing(flag1) make_thing(flag2) make_thing(flag3)" etc. it's possible to invoke that macro multiple times, with different definitions of make_thing, so as to achieve a power-of-two sequence of flag names as well as some other goodies.
For example, start by defining make_thing(x) as "LINEAR_ENUM_##x," (including the comma), and then use an enum statement to generate a list of enumerations (including, outside the make_things macro, LINEAR_NUM_ITEMS). Then create another enumeration, this time with make_thing(x) defined as "FLAG_ENUM_##x = 1<
Rather nifty some of the things that can be done that way, with flag and linear values automatically kept in sync; code can do nice things like "if (thingie[LINEAR_ENUM_foo] thing_errors |= FLAG_ENUM_foo;" (using both linear and flag values). Unfortunately, I know of no way to do anything remotely similar in C# or VB.net.

Related

Comparing 2 FileAttributes must always return true in C#

I recently got some great help here on stackoverflow. One of the answers puzzled me somewhat and I didn't feel it was appropriate to get an explanation due to the limitations of the comments box.
Please review the code below.
if ((File.GetAttributes(fileName) & FileAttributes.Archive) == FileAttributes.Archive)
{
// Archive file.
}
My question is why would you include the logic after the & (see bold)
(File.GetAttributes(fileName) & FileAttributes.Archive) == etc
Surely FileAttributes.Archive == FileAttributes.Archive will always match?
Does any one have an explanation to this (IMO it's probably a typo/mistake but I've assumed too many things before to only be corrected later on!)
The second question is what does the tilde ~ do in this code:
File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.Archive);
Some Enums are flags. That is, it can have any combination of the members of the enum and still be valid.
In the case of the FileAttributes enum, a file can be ReadOnly and Hidden at the same time. Likewise a file could be Hidden, ReadOnly and System. Writing an enum member for each combination would give 16 different members! Very inefficient.
When using flag-type enums, the way to check whether a value contains a specified enum member is to compare it with itself in a bitwise (binary) fashion.
Given the following simplified definition of the FileAttributes enum:
[Serializable, Flags]
public enum FileAttributes
{
Archive = 32,
Hidden = 2,
Normal = 128,
ReadOnly = 1,
System = 4,
Temporary = 256
}
A System file which is also marked ReadOnly will have the value 5 (4 + 1).
Trying to determine if the file is ReadOnly by using the code
File.GetAttributes(fileName) == FileAttributes.System
will evaluate as such:
5 == 4
and the result will be False.
The best way to determine whether the file has got the System attribute set is to do binary AND operation on the file's attribute and the attribute whose presence you want to determine. In code, you would write this:
(File.GetAttributes(fileName) & FileAttributes.System) == FileAttributes.System
This strips off all other attributes other than the System attribute before doing the comparison. Mathematically it would evaluate as such:
0101 (System + Hidden)
AND 0100 (System)
-------- -----------------
0100 (System)
Then the result (0100) would be compared to the System attribute (0100) and the result would then be True.
On one line, the code would be (0x0101 & 0x0100) == 0x0100 which evaluates to True.
Starting from .NET 4.0, Microsoft has included the Enum.HasFlag method to determine the presence or absence of flags in an enum value. You therefore do not have to type all that code yourself. When dealing with an Enum type that has the Flags attribute, you can simply use the HasFlag method to check if a particular flag is present. Your line would therefore be written as
File.GetAttributes(fileName).HasFlag(FileAttributes.System)
The tilde (~) mark, when used on a numeric value (or any type which can be 'degenerated' into int, uint, long or ulong), has the effect of flipping the bits on the number, producing the number's complement (all other values except the one specified).
For example, given the 16-bit number 4 (0x0100), it's complement (~4) would be 11 (0x1011)
0100 -> 1011
The tilde mark has the same effect as doing an XOR on the highest value of the type being compared. For a 16-bit number, the highest value would be 15 (1111) so your tilde will evaluate as:
0100
XOR 1111
--------
1011
The effect in your code File.SetAttributes(fileName, File.GetAttributes(fileName) & ~FileAttributes.Archive) will therefore get the file's attributes, remove the Archive attribute and then set it back to the file.
Assuming the file's attributes are Archive + Hidden, it will have a value of 34 (0x00100010) and ~Archive will have a value of 0x11011111.
Evaluating will be as such
(Archive + Hidden) 0x00100010
AND (~Archive) 0x11011111
---------------------- ----------
Hidden 0x00000010
The file's attributes will subsequently be changed to Hidden only (the Archive attribute will be removed).
The File.GetAttributes method returns an enumeration which has a Flags attribute that allows a bitwise combination of its member values. In other words, all the bit values of ALL of the relevant attributes are combined together in a single integer object. The '&' or bitwise and operator allows you to pull out the relevant bits of the object. The comparison with the original attribute is for clarity, it would be equally logically correct to simply look for a non-zero value.
http://msdn.microsoft.com/en-us/library/system.io.fileattributes.aspx
The problem is that FileAttributes has the Flags attribute. Means all the values can be combined (e.g. Archive AND Hidden).
To find out if really a specific value is set you have to mask out all the other values. For this purpose also the HasFlag method within the Enum class exists which could be used as follows in your example:
if(File.GetAttributes(fileName).HasFlag(FileAttributes.Archive))
{
// Archive file.
}
The second example does removing an exact value out of the bitmask. So it removes the archive attribute without touching all the other bits within the mask (e.g. readonly or hidden). For this task no method exists within the enum class.
It is a so named masked comparison.
(File.GetAttributes(fileName) & FileAttributes.Archive)
return FileAttributes.Archive
if there is a FileAttributes.Archive in attributes and return false in any other case.
Example:
if file attributes has value:
hidden archive readonly
1 1 0
bitwise and (File.GetAttributes(fileName) & FileAttributes.Archive)
returns
hidden archive readonly
0 1 0
and it is equal FileAttributes.Archive.
if file attributes has value:
hidden archive readonly
1 0 1
bitwise and (File.GetAttributes(fileName) & FileAttributes.Archive)
returns
hidden archive readonly
0 0 0
The '~' operator is a bitwise NOT (complement). See Bitwise Complement Operator

Why should I never use 0 in a flag enum [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Should an Enum start with a 0 or a 1?
Why should I never use 0 in a flag enum? I have read this multiple times now and would like to
know the reason :)
Why should I never use 0 in a flag enum?
The question is predicated on an incorrect assumption. You should always use zero in a flag enum. It should always be set to mean "None".
You should never use it for anything other than to represent "none of the flags are set".
Why not?
Because it gets really confusing if zero has a meaning other than "none". One has the reasonable expectation that ((e & E.X) == E.X) means "Is the X flag set?" but if X is zero then this expression will always be true, even if logically the flag is not "set".
Because Flag enums are bit collections, or sets of options.
A 0 value would be part of all sets, or of none. It just wouldn't work.
Although a zero means none of the bits are set, it is often very useful to have a named constant for 0.
When I set up flag words, I define the names of the bits so that they all represent the non-default value. That is, the enum value is always initialised to zero, turning 'off' all the options the bitfield represents.
This provides forwards compatibility for your enum, so that anyone who creates a new value knows that any zero bits are going to be 'safe' to use if you later add more flags to your bitfield.
Similarly it is very useful to combine several flags to make a new constant name, which makes code more readable.
The danger of this (and the reason for the rule you cite) is just that you have to be aware of the difference between single bit values (flags) and values that represent groups or combinations of bits.
Flag enums are used like this:
Flag flags = Flag.First | Flag.Next | Flag.Last;
Then you should define your Flag like this:
enum Flag {First = 1, Next = 2, Last = 4};
This way you can see if a Flag has been used e.g.:
if (flags & Flag.First <> 0) Console.WriteLine("First is set");
if (flags & Flag.Next <> 0) Console.WriteLine("Next is set");
if (flags & Flag.Last <> 0) Console.WriteLine("Last is set");
This is why you can only use values that is a power of 2 e.g. 1,2,4,8,16,32,64,128,...
If flags is 0 then it is considered blank.
I hope that this will increase your understanding of flag enums.
Because typically you use flags as follows:
var myFlagEnum = MyEnum.Foo | MyEnum.Bar | MyEnum.Bat;
// ... snip ...
if (myFlagEnum & MyEnum.Foo == MyEnum.Foo) { ... do something ... };
If the MyEnum.Foo were zero, the above wouldn't work (it would return true for all cases). Whereas if it were 1, then it would work.
A flag enum assumes that each one of it's values represents the presence of an option and it is coded in one of the enum's bits. So if a particular option is present (or true) the equiveland bit in the enum's value is set (1), otherwise it is not set (0)
so each one of the enum's fields is a value with only one bit set. If none of the options are present or true, then the combined enum's value is zero, which mean none of the bits are set. So the only zero field in a flag's enum, is the one that supposed to mean that no option is set, true, or selected.
For example assume we have a flags enum that encodes the presence of borders in a table cell
public enum BorderType
{
None = 0x00, // 00000000 in binary
Top = 0x01, // 00000001 in binary
Left = 0x02, // 00000010 in binary
Right = 0x04, // 00000100 in binary
Bottom = 0x08 // 00001000 in binary
}
if you want to show that a cell has the top and bottom borders present, then you should use a value of
Cell.Border = BorderType.Top | BorderType.Bottom; // 0x01 | 0x08 = 0x09 = 00001001 in binary
if you want to show that a cell has no borders present, then you should use a value of
Cell.Border = BorderType.None; // 0x00 = 00000000 in binary
So you should NEVER use zero as a value for an option in a flag enum, but you should always use zero as the value that means that none of the flags are set.
I really don't see the problem.
enum Where {Nowhere=0x00, Left=0x01, Right=0x02, Both=Left|Right};
Where thevalue = Where.Both;
bool result = (thevalue&Where.Nowhere)==Where.Nowhere;
Of course the result is true! What did you expect? Here, think about this.
bool result1 = (thevalue&Where.Left)==Where.Left;
bool result2 = (thevalue&Where.Right)==Where.Right;
bool result3 = (thevalue&Where.Both)==Where.Both;
These are all true! Why should Nowhere be special? There is nothing special about 0!

Inserting Multiple Values in a single Binary Field of SQL Server

I've come to an issue where i need to insert bit values(true/false) in my database for each hour for student attendance. For each hour there should be one value(true/false).
The straight forward option is create 24 columns and input value for each of them, every time a student is present. But definately this is also the worst one.
Someone suggest me to use binary field for it, one field could contain all these values.
Actually mu gui has 24 checkboxes and whichever checkbox is checked, its value should be stored as 1 so when next time i open the screem those checkboxes should remain checked.
I am using sql server 2008 and .net framework 4.0, if it helps.
Thanks
There is no need to mess with [var]binary(n). Since you only need 24 bits, store a regular, non-nullable int. Then just do bit-math on your code, i.e. shift (<< / >>) operators and bitwise combination (&, | and maybe some ~). Nothing else is needed. So if we decide that the LSB is 00:00, working right-to-left, then someone present at 03:00, and 14:00-16:00 (inclusive) would have a value of
(1 << 3) | (1 << 14) | (1 << 15) | (1 << 16) ==> 114696
If you aren't comfortable with bit-math, then either:
get comfortable with bit-math
don't try storing it as binary
You also state:
But definately this is also the worst one.
In what way? It describes your scenario, and SQL-server will condense multiple bit fields for you automatically. That might actually not be a bad option.
You can use the BitArray class for manipulating the individual bits of an int (and other types). This may make it easier for you to go with the binary option, however I don't think its necessarily a bad option to store all the values in the database.. Why do you think this is such a bad option?

When is a shift operator >> or << useful? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
When to use Shift operators << >> in C# ?
I've in programming a while and I've never used the shift operator. I could see how it could be helpful for calculating hash codes like in Tuple<T>, but other than that,
When and how is the shift operator useful in C#/.NET?
In general it's not used very often. But it's very useful when dealing with bit level operations. For example printing out the bits in a numeric value
public static string GetBits(int value) {
var builder = new StringBuilder();
for (int i = 0; i < 32; i++) {
var test = 1 << (31 - i);
var isSet = 0 != (test & value);
builder.Append(isSet ? '1' : '0');
}
return builder.ToString();
}
It's useful to write powers of two.
Quick: What's 227?
Answer: 1 << 27
Writing 1 << 27 is both easier and more understandable than 134217728.
I use it rather a lot in dealing with hardware. This isn't something you probably do in C# a lot, but the operator was inherited from C/C++ where it is a fairly common need.
Example 1:
I just got a longword from a little-endian machine, but I'm big endian. How do I convert it? Well, the obvious is call htonl() (you cheater). One of the manual ways to do it is with something like the following:
((source & 0x000000ff) << 24 ) |
((source & 0x0000ff00) << 8) |
((source & 0x00ff0000) >> 8) |
((source & 0xff000000) >> 24);
Example 2:
I have a DMA device that only allows longword accesses of up to 512K. So it requires me to put (for reasons only understood by hardware folks) the modulo 4 of the transfer size into the high order 18 bits of a DMA transfer control register. For the sake of arguement, the low-order bits are to be filled with various flags controlling the DMA operation. That would be accomplished like so:
dma_flags | ((length & 0xffffc) << 14);
These might not be the kind of things you do every day. But for those of us that regularly interface to hardware they are.
If you ever need to multiply without using * How to implement multiplication without using multiplication operator in .NET :)
Or write a Sudoku solver Sudoku validity check algorithm - how does this code works?
In practice, the only time I've seen it used in my (limited) experience was as an (arguably) confusing way to multiply (see first link) or in conjunction with setting BitFlags (the Sudoku solver above).
In .NET I rarely have to work at the bit level; but if you need to, being able to shift is important.
Bitwise operators are good for saving space, but nowadays, space is hardly an issue.
It's useful when multiplying by powers of 2
number<<power;
is number*2^power
And of course division by powers of 2:
number>>power;
Another place is flags in enums.
when you come across code like
Regex re = new Regex(".",RegexOptions.Multiline|RegexOptions.Singleline);
the ability to use RegexOptions.Multiline|RegexOptions.Singleline i.e multiple flags is enabled through the shifting and also this allows them to be unique.
Something like:
enum RegexOptions {
Multiline = (1 << 0),
Singleline = (1<<1)
};
Bit shifts are used when manipulating individual bits is desired. You'll see a lot of bit shifts in many encryption algorithms, for example.
In optimization, it can used in place of multiplication/division. A shift left is equal to multiplying by two. Shift right equals division. You probably don't see this done anymore, since this level of optimization is often unnecessary.
Other than that, I can't think of many reasons to use it. I've seen it used before, but rarely in cases where it was really required and usually a more readable method could have been used.
Whenever you need to multiply by 2 ;)
Really the only use I have is for interoperability code and bitfields:
http://www.codeproject.com/KB/cs/masksandflags.aspx

How does a logical & work on two bytes in C#?

I recently had a test question:
byte a,b,c;
a = 190;
b = 4;
c = (byte)(a & b);
What is the value of c?
I have never used a logical operand in this manner, what's going on here? Stepping through this, the answer is 4, but why?
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
You are doing a bitwise AND in this case, not a logical AND, it is combining the bits of the two values of a & b and giving you a result that has only the bits set that are both set in a & b, in this case, just the 4s place bit.
190 = 10111110
& 4 = 00000100
-------------------
= 4 00000100
Edit: Interestingly, msdn itself makes the issue of whether to call it logical vs bitwise a bit muddy. On their description of the logical operators (& && | || etc) they say logical operators (bitwise and bool) but then on the description of & itself it indicates it performs a bitwise AND for integers and a logical AND for bools. It appears it is still considered a logical operator, but the action between integer types is a bitwise AND.
http://msdn.microsoft.com/en-us/library/sbf85k1c(v=vs.71).aspx
The logical AND operator, when applied to integers performs a bitwise AND operation. The result is 1 in each position in which a 1 appears in both of the operands.
0011
& 0101
------
0001
The decimal value 190 is equivalent to binary 10111110. Decimal 4 is binary 00000100.
Do a logical AND operation on the bits like this:
10111110
& 00000100
----------
00000100
So the result is 4.
Also, where would this come up in the real world? I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
These operations are useful in several circumstances. The most common is when using Enum values as flags.
[Flags]
public enum MyFileOptions
{
None = 0,
Read = 1, // 2^0
Write = 2, // 2^1
Append = 4, // 2^2
}
If an Enum has values that are powers of two, then they can be combined into a single integer variable (with the Logical OR operator).
MyFileOptions openReadWrite = MyFileOptions.Read | MyFileOptions.Write;
In this variable, both bits are set, so it indicates that both the Read and Write options are selected.
The logical AND operator can be used to test values.
bool openForWriting = ((openReadWrite & MyFileOptions.Write) == MyFileOptions.Write);
NOTE
A lot of people are pointing out that this is actually a bitwise AND not a logical AND. I looked it up in the spec before I posted, and I was suprised to learn that both versions are referred to as "Logical AND" in the spec. This makes sense because it is performing the logical AND operation on each bit. So you are actually correct in the title of the question.
This is a bitwise AND, meaning the bits on both bytes are compared, and a 1 is returned if both bits are 1.
10111110 &
00000100
--------
00000100
One of the uses of a logical & on bytes is in networking and is called the Binary And Test. Basically, you logical and bytes by converting them to binary and doing a logical and on every bit.
In binary
4 == 100
190 == 10111110
& is and AND operation on the boolean operators, so it does de Binary and on 4 and 190 in byte format, so 10111110 AND 100 gives you 100, so the result is 4.
This is a bitwise AND, not a logical AND. Logical AND is a test of a condition ie:
if(a && b) doSomething();
A bitwise AND looks at the binary value of the two variables and combines them. Eg:
10101010 &
00001000
---------
00001000
This lines up the binary of the two numbers, like this:
10111110
00000100
--------
00000100
On each column, it checks to see if both numbers are 1. If it is, it will return 1 on the bottom. Otherwise, it will return 0 on the bottom.
I would argue that using logical operands in this manner, with a cast, is just bad practice, but I could be wrong.
There is no cast. & is defined on integers, and intended to be used this way. And just so everyone knows, this technically is a logical operator according to MSDN, which I find kind of crazy.

Categories