Not many takers on WWWTC #15, but Jason finally nailed it.
The bug in the code revolves around how VB allocates arrays. The following code snippet creates an array of 5 System.Char objects, and will output the number 5 to the screen, right?
Dim length As
Integer = 5
Dim chars()
As
Char = New Char(length)
{}
Console.WriteLine(chars.Length)
The output is "6", which still astonishes those of us (me, at least) who hail from the land of semicolons. The number I pass to the New clause in VB doesn't specify the number of elements in the array, but the upper bounds of the array. Passing a 5 tells VB to create an array with 6 elements indexed 0 to 5.
I suspect this behavior is a compromise over the definition of an array's lower bound. Does an array start at 0? Does an array start at 1? It's a religious debate, but a VB developer could use the chars array like so:
For i As
Integer = 0
To 4
Console.WriteLine(chars(i))
Next
... or like so:
For i As
Integer = 1
To 5
Console.WriteLine(chars(i))
Next
... and neither will fail with an index out of bounds exception.
This behavior does cause a problem, however, when you want a precise number of characters and forget how New works. The unit test failed because it expected to get back a string with a length of 6 ("edoCoTedO"), but the actual string had a length of 7 (with a 0 character tacked on the end).
The fix is to create the array by passing the length of the string minus 1.
Comments
try in C# next time =oP
I'm not saying array lengths in vb aren't confusing (I stick to ArrayLists for this reason :), but there are ways to make the code more understandable.
Dim chars() As Char = New Char(0 To length) {}
This is valid code so long as the lower bound is only ever zero, but to anyone reading the code it is now obvious where the problem is.
ReDim chars(0 To input.Length - 1)
It's a bit old school, I admit; but it probably documents itself a little better if the code might be reviewed by sharp-types.