Previous | Index | Next 

[PRB] VB6 and VB.NET store arrays into Collection objects in different ways

Consider the following, apparently innocent piece of VB code:

        ' create and initialize an array
        Dim arr(10) As Integer
        arr(0) = 100
        ' store it into a collection
        Dim col As New Collection
        col.Add(arr)
        ' modify the array, compare with the array in the collection
        arr(0) = 200
        If arr(0) = col(1)(0) Then
            txtResult.Text = "Equal"
        Else
            txtResult.Text = "Not equal"
        End If

Quite surprisingly this code shows different results in VB6 and VB.NET. More precisely, it displays "Not Equal" under VB6 and "Equal" under VB.NET.
The reason is, when passing the array to the Collection.Add method, VB6 performs a copy of the array, therefore the subsequent assignment to arr(0) doesn't affect the copy already stored in the collection and the two arr(0) elements are now different. Vice versa, VB.NET passes a reference to the System.Array object, therefore there is only one array in memory and the assignment to arr(0) affects the same array as seen from the Collection.
This behavior can be the cause of a very subtle bug when converting a complex VB6 application to .NET, Once you see where the problem is, you can fix it by simply cloning the array being stored to the collection

        col.Add(arr.Clone())

As of version 1.21, VB Migration Partner doesn’t automatically insert the call to the Clone method, even though we plan to add this feature in a future version. In the meantime you can avoid the problem by replacing the Microsoft.VisualBasic.Collection with either the VB6Collection object or the new Collection6 object (added in version 1.21). Such a replacement can be done automatically for all Collection objects with a project-level PostProcess pragma:

        '## project:PostProcess "\b(?<=(As|Is|New)\s+)(VBA\.)?Collection\b", "Collection6"

Note that this step is never required when converting to C#, because in this case the VBA.Collection object is converted to the Collection6 object (defined in VB Migration Partner’s support library), that automatically performs a copy of all arrays when they are added to the inner collection.

 

Previous | Index | Next