Today I investigated a logical bug in our software and figured out that this is related to the way VB.NET thread variables inside a loop.
Let's say I have the following code:
Dim numbers As New List(Of Integer) From {1, 2, 3, 4, 5}
For Each number As Integer In numbers
Dim isEven As Boolean
If number Mod 2 = 0 Then
isEven = True
End If
If isEven Then
Console.WriteLine(number.ToString() & " is Even")
Else
Console.WriteLine(number.ToString() & " is Odd")
End If
Next
produces the following output
1 is Odd
2 is Even
3 is Even
4 is Even
5 is Even
The problem is that isEven
is declared but not assigned.
In this specific case, it would be correct to write dim isEven as Boolean = false
but I haven't done this.
In VB.NET, a variable that is declared inside a for loop keeps its value for the next itaration. This is by design: http://social.msdn.microsoft.com/Forums/en/vblanguage/thread/c9cb4c22-d40b-49ff-b535-19d47e4db38d but this is also dangerous pitfall for programmers.
However, until now, I haven't been aware of this problem/behaviour. Until now. Most of our code base is C# anyway, which doesn't allow the use of an uninitialized variable, so there is no problem.
But we have some legacy code that is written in VB.NET that we have to support.
I don't think that anyone of our dev team has ever used this with purpose. If I explicitly want to share a variable over iterations inside a for loop, I declare it outside the scope.
So the best thing would be to generate a warning or even an error in this specific case. But even with Option Explicit / Option Strict this does not generate a warning / an error.
Is there a way make this a compile time error or maybe a way to check this with FxCop?