This is expected behavior.
As you mention in a comment to another answer, it's probably easier to see using integers rather than string concatenation:
Sub Main()
For i As Integer = 0 To 5
Dim j As Integer = j + 1
Console.WriteLine(j.ToString())
Next
End Sub
The output is as follows:
1
2
3
4
5
6
To learn why, we turn to the documentation, specifically the section on scope. The j
variable that you've declared is at block scope, because it is declared inside of the For
block. However, variables that are declared at block scope still retain their values for the entire duration of their containing procedure. As the documentation says in a note:
Even if the scope of a variable is limited to a block, its lifetime is still that of the entire procedure. If you enter the block more than once during the procedure, each block variable retains its previous value. To avoid unexpected results in such a case, it is wise to initialize block variables at the beginning of the block.
So what's happening is that each time you re-enter the For
block, j
still has its previous value. Because the right-side of the equals sign is evaluated first, that old value of j
is incremented by 1, and then stored in j
(effectively erasing the old contents of j
).