Using enumerations?

cjard

Well-known member
Joined
Apr 25, 2006
Messages
7,081
Programming Experience
10+
When working with datatables we can indicate we want changed and added rows with:

Dim chg as DataTable = realDatatable.GetChanges(Added+Modified)


Added and Modified are integer constants in the DataRowState enum..
The code above doesnt work with Option Strict on because added+modified is an integer type result not a datarowstate type result

Currently I just cast this integer result back into a datarowstate, but i cant help feeling that its just a bit messy and awkward.. If DRS is already an integer, why does the compiler take exception to me supplying it?
 
You have to use the bitwise operator And to combine the enums, not the aritmethic addition operator +
VB.NET:
Dim chg As DataTable = realDatatable.GetChanges(DataRowState.Added And DataRowState.Modified)
(I don't know if you meant Added as a shortening of posted description (pseudo code), but you have to qualify the enumeration member with the enumeration you are taking the enumeration value from.. if you geddit; yes DataRowState.Added, no Added)
 
Thanks for the shove in the right direction :).. but i have another question now: surely + is Or? because a row cannot be changed AND added?

1 Or 2 = 3
1 And 2 = 0
2 And 6 = 2


(and ye.. the Added+Mod was pseudocode.. i'll be less lazy next time.. :) )
 
Last edited by a moderator:
OR it is when combining, yes, even though it doesn't sound logical right.
 
Aww, cmon man.. I thought that might at least raise a "Doh!" from you...
:)

JohnH said:
You have to use the bitwise operator And to combine the enums, not the aritmethic addition operator +
JohnH said:
OR it is when combining, yes, even though it doesn't sound logical right

Well, made me chuckle anyways.. Kinda a reminder that even JohnH is human :D


On which sounds logical:
"Get me all rows who have rowstate modified and new"
"Get me all rows who have rowstate modified or new"
Being heavy into sql development as a job facet, the second actually reads more logically to me :)

It kinda takes me back to a talk i was having with a guy about = NULL vs IS NULL.. He really wanted to use =NULL and i said he couldnt because NULL was special and as such, required special treatment. the boffins at oracle had chosen to make NULL = NULL evaluate to false (disagreeing somewhat with the boffins at microsoft, then) and he couldnt understand it because he thought it sounded more logically right than NULL IS NULL.. he was even up for emailing oracle and asking for it to be changed.. :)
 
Note that when you use Or and And in this situation you are using them as bitwise operators, not logical operators. As such it doesn't sound logical because it's not logical, it's bitwise.
 
As an aside.. how does VB know? What if one of the operands were a boolean? (i know it's a programming error to make, but just incase it's a gotcha that breaks my/someone's code, i'd like to know.)

i.e for the following operand pairings:

Integer And Integer <- Bitwise ?
Boolean And Boolean <- logical ?
Integer And Boolean <- what?
 
I'm going to have a stab and say bitwise just because boolean data is (or atleast it was) stored as an integer. Like i say this is just a stab, i've no doubt that i'll be corrected if i stabbed it wrong.:)
 
If you have Option Strict On, which everyone should, then the compiler will not let you use And or Or with an Integer and a Boolean operand. Regardless of the order it says that the Boolean cannot be converted to an Integer. If you have Option Strict Off then the result of Anding or Oring an Integer and a Boolean is an Integer, again regardless of the order. Therefore bitwise takes precedence over logical. Just type it into the IDE and see for yourself. No need to guess.
 
As a bit of an aside, note also that for bitwise combinations of enumerated types to be useful the enumeration must be declared with the Flags attribute, in case you wanted to try it yourself some time.
 
I looked up about the flags attribute, and i'm a little unsure of why it is needed? The examples i saw and advice from msdn was that your enum values had to be powers of 2, and [Flags] would not do this for you.. So if it doesnt enforce power-of-2 for bitwise ops, what does it do?
 
Looks like the Flags attribute performs some kind of cosmetic operation when you get an enum type as a string. Do a combine for both enums with and without the flag and check their ToString representation. Same as in the FlagsAttribute Class documentation example you'll see this gives different strings, one with the numerical representation of the combination and one with a list of the combined members. This is of course important when you list the enum members for user to select, and even more important for enum members that already represent a combination of other enum members.
 
The Flags attribute works by assigning values to the enumerated constants such that each one has a single, distict bit set in its binary value. That's how you're able to do bitwise operations on them. Here's an example of a regular enumeration and the binary values of each constant. I've used 8-bit rather than 32 to make it easier:
VB.NET:
Public Enum MyEnum
    Const0 '00000000 = 0
    Const1 '00000001 = 1
    Const2 '00000010 = 2
    Const3 '00000011 = 3
    Const4 '00000100 = 4
    Const5 '00000101 = 5
    Const6 '00000110 = 6
    Const7 '00000111 = 7
End Enum
Now here's an example of how the values are assigned if the type is decorated with the Flags attribute:
VB.NET:
<Flags()> Public Enum MyEnum
    Const0 '00000001 = 1
    Const1 '00000010 = 2
    Const2 '00000100 = 4
    Const3 '00001000 = 8
    Const4 '00010000 = 16
    Const5 '00100000 = 32
    Const6 '01000000 = 64
    Const7 '10000000 = 128
End Enum
As you can see, with the Flags attribute applied each constant has a single, distinct bit set in its binary representation. That means that in a combined value you simply test the bit that corresponds to a particular constant to see if the combined value includes that value. Let's say you wanted a combined value that included Const1, Const4 and Const7. You would use this expression:
VB.NET:
Dim myVal As MyEnum = Const1 Or Const4 Or Const7
and here's how the value is calculated:

00000010 Or
00010000 Or
10000000
---------
10010010

so each bit is set in the result if that bit is set in Const1 OR Const4 OR Const7. That's why you use Or.

You use the And bitwise operator to test whether a combined value contains a specific value. Let's say we have the value above and we want to test whether it contains the value Const4. You would use an expression like this:
VB.NET:
If (myVal And Const4) = Const4 Then
and here's how the calculation is pefromed:

10010010 And
00010000
---------
00010000

so each bit is set in the result if that bit is set in the combined value AND in Const4. That's why you use And. As you can see, the result is equal to Const4, so we know that the combined value included Const4. If you wanted to check if the same combined value contained Const3 you would use:
VB.NET:
If (myVal And Const3) = Const3 Then
and the calculation would go:

10010010 And
00001000
---------
00000000


As you can see, the result does not equal Const3 so the combined value does not contain Const3.
 
The Flags attribute does not assign any values, you have to do that yourself, and you must do it in powers of two to avoid overlapping if the bitwise operations should have any value.
 
JohnH said:
The Flags attribute does not assign any values, you have to do that yourself, and you must do it in powers of two to avoid overlapping if the bitwise operations should have any value.
Well there you go. :eek: Obviously I've only ever used enumerations with the Flags attribute before and not actually defined any. I was under the impression that the Flags attribute altered the way an enumeration was defined, but apparently it only alters the way it is handled. My apologies.
 
Back
Top