VB Migration Partner

KNOWLEDGE BASE - Language


Previous | Index | Next 

[PRB] .NET collections can’t be modified while inside a For Each loop

VB6 and VB.NET collections differ in a substantial way: you can’t modify a VB.NET collection (or any .NET collection, for that matter) from inside a For Each loop that is iterating over the collection itself. You see the problem in the following piece of code, which is quite common in VB6:

        ' unload all forms
        Dim frm As Form
        For Each frm In Forms
            Unload frm
        Next

The code is translated almost literally to .NET:

        ' VB.NET
        Dim frm As VB6Form
        For Each frm In Forms6
            Unload6(frm)
        Next
        
         // C#
	foreach (VB6Form frm in VBProject.Forms)
	{
		VB6Helpers.Unload(frm);
	}

When you run the above code, the Next statement throws an InvalidOperationException error whose message is quite self-explanatory:

Collection was modified; enumeration operation may not execute.

VB Migration Partner doesn’t fix this issue automatically. However, you can edit the original VB6 code to use the CloneCollection6 method defined in VBMigrationPartner_Support.bas module:

        ' unload all forms
        Dim frm As Form
        For Each frm In CloneCollection6(Forms)
            Unload frm
        Next

When converting to C#, you have slightly modify the code so that it uses the method defined in the VB6Helpers class:

        
         // C#
	foreach (VB6Form frm in VB6Helpers.CloneCollection(VBProject.Forms))
	{
		VB6Helpers.Unload(frm);
	}

The VB6 version of the CloneCollection6 method simply returns its argument, therefore the original program isn’t affected in any way. The .NET version of the method (defined in the support library) creates and returns a copy of the original collection, therefore the loop iterates on a collection instance other than the instance being modified in the loop itself and no runtime error occurs.

In a few special cases you might prefer not to create a clone of the original collection, for example if the collection has too many elements and the copy operation would add a noticeable overhead. In such special cases, you can avoid the issue by replacing the For Each block with a regular For loop, as in:

        Dim i As Integer
        For i = Forms.Count – 1 To 0 Step -1 
            Unload Forms(i)
        Next

or

        Dim i As Integer
        For i = 1 To Forms.Count
            Unload Forms(0)
        Next
Previous | Index | Next 




Follow Francesco Balena on VB6 migration’s group on

LinkedIn





Read Microsoft Corp’s official case study of a VB6 conversion using VB Migration Partner.




Code Architects and its partners offers remote and onsite migration services.

More details




Subscribe to our free newsletter for useful VB6 migration tips and techniques.

newsletter



To learn more about your VB6 applications, run VB6 Analyzer on your source code and send us the generated text file. You will receive a detailed report about your VB6 applications and how VB Migration Partner can help you to quickly and effectively migrate it to .NET.

Get free advice



A fully-working, time-limited Trial Edition of VB Migration Partner allows you to test it against your actual code

Get the Trial




The price of VB Migration Partner depends on the size of the VB6 application, the type of license, and other factors

Request a quote




Migrating a VB6 application in 10 easy steps

Comparing VB Migration Partner with Upgrade Wizard

Migration tools: Feature Comparison Table

All whitepapers