Hopefully I am posting this in the correct place. If not, please help me get there. Basically I want to report a bug with the VB2005 (and VB.NET 2003) compiler.
Here is the behavior: In VB2005 (and VB.NET 2003), Enumeration comparison to Integer with Option Strict On never implicitly converts the enumeration to the integer, and also does not show up as an error in the pre-compiler or the compiler. Thus it will incorrectly evaluate to false, even if it is true.
I am part of a team where I work, and we have a very large solution that we recently converted to VB2005 (after turning on Option Strict). We came across this error when our application had some undesirable results.
I blogged about this here: http://robz.homedns.org:8080/blog/archive/2006/02/28/1814.aspx
Visual Basic 2005 (& VB.NET 2003) Hard Lesson #1 : Enumeration Comparison to Integer
Let's say you use Option Strict in VB. If you use an enumeration, you have to explicitly cast it if you are going to compare the value to an integer based value, but the compiler will not tell you that. If you put the information in the watch window or the immediate window, it looks like it is evaluating to true, but it is not.
Let's explore this, shall we
Dim intArray() As Integer = {myEnumeration.ValueOfZero,myEnumeration.ValueOfOne,myEnumeration.ValueOfTwo} ' becomes {0,1,2} implicitly
Dim visible As Boolean = (Not Array.IndexOf(intArray, myEnumeration.ValueOfOne) = -1) ' does not implicitly cast the enumeration value to it's integer value, thus evaluates to false
visible = (Not Array.IndexOf(intArray, CInt(myEnumeration.ValueOfOne)) = -1) ' correctly evaluates to true
Both property settings (for visible) look almost exactly the same, and you would expect the same results. Both should evaluate to True, but the first one evaluates to false. The precompiler and the compiler do not warn you of this error like they should. We would like to call this a bug, because it is definitely unexpected behavior. Do you see what is causing the problem Creating the array as an integer, instead of the enumeration type. What you should do instead is:
Dim enumerationArray() As myEnumeration = {myEnumeration.ValueOfZero,myEnumeration.ValueOfOne,myEnumeration.ValueOfTwo}
This still doesn't account for the fact that this is still a bug that should be evaluated by Microsoft. Why I don't believe the watch windows or the immediate window make use of Option Strict even when you use it in the project. So it will look like the example is evaluating to true everywhere but in the running code. Therefore, although I would never recommend a developer coding like the above example, there is potential for someone to look at this and not catch the error for a long time because it will look like it is evaluating to True to someone debugging the code.
UPDATE: We have verified that this behavior exists in the VB2003 Compiler as well.

VB2005 & VB.NET 2003 BUG: Enumeration Comparison to Integer with Option Strict On does not evaluate correctly
JavaGuy147
Here is the explanation:
Two different overloads of Array.IndexOf() are invoked for the two lines bellow.
Dim a As Integer = Array.IndexOf(intArray, myEnumeration.ValueOfOne)
Dim b As Integer = Array.IndexOf(intArray,CInt(myEnumeration.ValueOfOne))
But this is not the main reason. It is about how Array.IndexOf() works (see http://msdn2.microsoft.com/en-us/library/7eddebat.aspx).
First, myEnumeration.ValueOfOne is boxed and passed to Array.IndexOf() which takes each element of the array and compare it against the value. The comparison is done using the method Object.Equals(). (see http://msdn2.microsoft.com/en-us/library/bsc2ak47.aspx ).
As a high level language, VB is more user friendly and automatically converts an enum to its underlying integer value when comparing or passing it for an integer.
Object.Equals() is a low level CLR function and it is more restrictive. Basically myEnumeration.ValueOfOne and the integer “1” are different because they are different types.
Just play with the code lines bellow and the difference will be obvious.
Dim o1 As Object = myEnumeration.ValueOfOne
Dim o2 As Object = 1
Dim rez As Boolean = o1.Equals(o2)
Dim e1 As myEnumeration = myEnumeration.ValueOfOne
Dim e2 As Integer = 1
Dim rez2 As Boolean = (e1 = e2)
Dim rez3 As Boolean = myEnumeration.ValueOfOne.Equals(1)
Dim rez4 As Boolean = myEnumeration.ValueOfOne.Equals(o1)
Dim intArray() As Integer = {myEnumeration.ValueOfZero, myEnumeration.ValueOfOne, myEnumeration.ValueOfTwo} ' becomes {0,1,2} implicitly
Dim a As Integer = Array.IndexOf(intArray, myEnumeration.ValueOfOne)
Dim b As Integer = Array.IndexOf(intArray, CInt(myEnumeration.ValueOfOne))
Dim visible As Boolean = (Not Array.IndexOf(intArray, myEnumeration.ValueOfOne) = -1) ' does not implicitly cast the enumeration value to it's integer value, thus evaluates to false
visible = (Not Array.IndexOf(intArray, CInt(myEnumeration.ValueOfOne)) = -1) ' correctly evaluates to true
Why the VB compiler does not insert automatically the cast “CInt” Because Array.IndexOf() is like any other method call and the second param has type object. All the compiler can do is to box “myEnumeration.ValueOfOne” and pass it as Object.
The similar code in C# will show the same behavior, except C# will ask always for explicit cast from enum to integer.
Such differences between high level languages and the low level runtime are common. It is something we can explain but it is not much MS team can fix here.
However the finding is interesting and valuable. It is going to help other people to avoid this trap and we are very thankful for posting it.
Many thanks,
Corneliu Barsan
jero529
http://lab.msdn.microsoft.com/ProductFeedback/viewfeedback.aspx feedbackid=f621e36b-7ddb-42a9-89e5-d0e84e4d237d&lc=1033
Found where to submit bugs. :)
Le Van Quy
Thanks for your quick reply. One interesting thing to note is that if you turn OFF Option Strict, it will cast the enumeration correctly to integer and evaluate correctly.
TheSoddy