Code Refactoring

The Visual Basic Upgrade Companion analyzes the VB6 code to detect patterns that can be upgraded to native .NET structures. Some of these patters are:

IF ELSE IF structures to SWITCH

Some "if else if" constructs are upgraded to "switch" or "Select Case" construct in order to improve performance and use best programming practices.

Visual Basic 6.0 code
Sub Foo(ByVal strvar As String)
    Dim start as Integer
    If (strvar = "META") Then
        start = 1
    ElseIf (strvar = "MART") Then
        start = 2
    ElseIf (strvar = "OP") Then
        start = 3
    End If
End Sub
VB.NET: VB Upgrade Wizard generated code
Sub Foo(ByRef strvar As String)
    Dim start As Integer
    If (strvar = "META") Then
        start = 1
    ElseIf (strvar = "MART") Then
        start = 2
    ElseIf (strvar = "OP") Then
        start = 3
    End If
End Sub
VB.NET: Visual Basic Upgrade Companion generated code
Sub Foo(ByVal strvar As String)
    Dim start as Integer
    Select Case strvar
        Case "META"
            start = 1
        Case "MART"
            start = 2
        Case "OP"
            start = 3
    End Select
End Sub
C#: Visual Basic Upgrade Companion generated code
void Foo(string strvar) 
    int start = 0;
    switch(strvar)    
        case "META" :
            start = 1;
            break;
        case "MART" :
            start = 2;
            break;
        case "OP" :
            start = 3;
            break;

Return instead of function name to set the return value

Visual Basic Upgrade Companion uses the return statement instead of the function name to set the return value of a function. It avoids the common error to assign the return value a variable instead of the function name because there was a mistake in the written function name. Also it makes it easy to identify the exit point of a function or property.

Example 1:
Visual Basic 6.0 code
Function MultiplyAndSum(b As Boolean, x1 As Integer, x2 As Integer) As Integer
    If b = True Then
        x1 = x1 + 5
        x2 = x2 + 10
        MultiplyAndSum = x1 + x2
    Else    
        x1 = x1 * 5
        x2 = x2 * 10
        MultiplyAndSum = x1 * x2
    End If
End Function
VB.NET: VB Upgrade Wizard generated code
Function MultiplyAndSum(ByRef b As Boolean, ByRef x1 As Short, ByRef x2 As Short) As Short
    If b = True Then
        x1 = x1 + 5
        x2 = x2 + 10
        MultiplyAndSum = x1 + x2
    Else
        x1 = x1 * 5
        x2 = x2 * 10
        MultiplyAndSum = x1 * x2
    End If
End Function
VB.NET: Visual Basic Upgrade Companion generated code
Function MultiplyAndSum(ByVal b As Boolean, ByRef x1 As Short, ByRef x2 As Short) As Short
    If b Then
        x1 += 5
        x2 += 10
        Return x1 + x2
    Else
        x1 *= 5
        x2 *= 10
        Return x1 * x2
    End If
End Function
C#: Visual Basic Upgrade Companion generated code
int MultiplyAndSum( bool b, ref int x1, ref int x2)
    if (b)
        x1 += 5;
        x2 += 10;
        return x1 + x2;
    else
        x1 *= 5;
        x2 *= 10;
        return x1 * x2;
}
Example 2:
Visual Basic 6.0 code
Function MultiplyAndSum2(b As Boolean, x1 As Integer, x2 As Integer) As Integer
    MultiplyAndSum2 = 500
    If b = True Then
        x1 = x1 + 5
        x2 = x2 + 10
        MultiplyAndSum2 = MultiplyAndSum2 + x1 + x2
    Else
        x1 = x1 * 5
        x2 = x2 * 10
        MultiplyAndSum2 = x1 * x2
    End If
End Function
VB.NET: VB Upgrade Wizard generated code
Function MultiplyAndSum2(ByRef b As Boolean, ByRef x1 As Short, ByRef x2 As Short) As Short
    MultiplyAndSum2 = 500
    If b = True Then
        x1 = x1 + 5
        x2 = x2 + 10
        MultiplyAndSum2 = MultiplyAndSum2 + x1 + x2
    Else
        x1 = x1 * 5
        x2 = x2 * 10
        MultiplyAndSum2 = x1 * x2
    End If
End Function
VB.NET: Visual Basic Upgrade Companion generated code
Function MultiplyAndSum2(ByVal As BooleanByRef x1 As IntegerByRef x2 As IntegerAs Integer
    Dim result As Integer = 0
    result = 500
    If Then
        x1 += 5
        x2 += 10
        result = result + x1 + x2
    Else
        x1 = x1 * 5
        x2 = x2 * 10
        result = x1 * x2
    End If
    Return result
End Function
C#: Visual Basic Upgrade Companion generated code
int MultiplyAndSum2( bool b, ref int x1, ref int x2)
    int result = 500;
    if (b) 
        x1 += 5; 
        x2 += 10; 
        return result + x1 + x2; 
    else 
        x1 *= 5; 
        x2 *= 10; 
        return x1 * x2;
    return result;
}

Collections to ArrayList or HashTable

The Visual Basic Upgrade Companion upgrades Collections to ArrayList or HashTable depending on their usage. For example, the .NET HashTable class is several times faster than the Collection class. So, when the Visual Basic Upgrade Companion detects that a Collection is used as a HashTable (keys and values) it upgrades the Collection to a HashTable.

Example:

As a simple reference, the following table shows the execution time for the three implementations of the same example. The code generated by the Visual Basic Upgrade Companion is about 4.3 times faster than the code produced by the Visual Basic Upgrade Wizard.

Implementation Execution Time
Visual Basic 6.0 code 16 seconds
.NET: VB Upgrade Wizard generated code 13 seconds
.NET: Visual Basic Upgrade Companion generated code 3 seconds

These three implementations were executed on the same machine with the following configuration:

  • Pentium IV
  • 1.6 Mhz
  • 512 MB of RAM
Visual Basic 6.0 code
Dim ck As New Collection
Dim Time
Time = Now
For i = 1 To 200000
    ck.Add Item:="Item", Key:="Item" & CStr(i)
Next i
For i = 1 To 200000
    ck.Remove("Item" & CStr(i))
Next i
Total = Now -Time
MsgBox Format(Total, "hh:mm:ss"), Title:="Time"
VB.NET: VB Upgrade Wizard generated code
Dim Total As Date
Dim i As Integer
Dim ck As New Collection
Dim Time As Date
Time = Now
For i = 1 To 200000
    ck.Add("Item", "Item" & CStr(i))
Next i
For i = 1 To 200000
    ck.Remove(("Item" & CStr(i)))
Next i
Total = System.Date.FromOADate(Now.ToOADate -Time.ToOADate)
MsgBox(VB6.Format(Total, "hh:mm:ss"), , "Time")
VB.NET: Visual Basic Upgrade Companion generated code
Dim ck As System.Collections.Hashtable = New System.Collections.Hashtable
Dim Time As Date = DateTime.Now
For i As Integer = 1 To 200000
    ck.Add("Item" & i.ToString(), "Item")
Next i
For i As Integer = 1 To 200000
    ck.Remove("Item" & i.ToString())
Next i
Dim Total As Double = DateTime.Now.AddDays-Time.ToOADate()).ToOADate())
MessageBox.Show(Date.FromOADate(Total).ToString("HH:MM:ss"), "Time")
C#: Visual Basic Upgrade Companion generated code
Hashtable ck = new Hashtable();
System.DateTime Time = DateTime.Now;
for (long i = 1; i <= 200000; i++ )
    ck.Add("Item" + i.ToString(), "Item");
for (long i = 1; i <= 200000; i++ )
    ck.Remove("Item" + i.ToString());
double Total = DateTime.Now.AddDays(-Time.ToOADate()).ToOADate();
MessageBox.Show(DateTime.FromOADate(Total).ToString("HH:MM:ss"), "Time");

Use For … Each statement instead of a iteration variable

The Visual Basic Upgrade Companion detects some common programming patterns in VB6 and changes them to "for … each" statements.

This change reduces the number of lines of code and generates more legible .NET code by using specialized language structure to iterate.

This example shows how the "for" loop statement and the call to the function Mid, are changed to a "for … each" statement.

Visual Basic 6.0 code
Dim i As Integer
Dim Description As String
Description = "hello world"
For i = 1 To Len(Description)
    strChar = Mid(Description, i, 1)
    MsgBox(strChar)
Next
VB.NET: VB Upgrade Wizard generated code
Dim i As Integer
Dim Description As String
Description = "hello world"
For I = 1 To Len(Description)
    strChar = Mid(Description, I, 1)
    MsgBox(strChar)
Next
VB.NET: Visual Basic Upgrade Companion generated code
Dim Description As String = "hello world"
For Each strChar As Char In Description
    MessageBox.Show(strChar)
Next strChar
C#: Visual Basic Upgrade Companion generated code
string Description = "hello world";
foreach (char strChar in Description)
    MessageBox.Show(strChar.ToString());

Move initialization values to the variable declaration

Unlike VB.NET, Visual Basic 6.0 syntax does not allow programmers to initialize variables when declared. When upgrading to .NET, the Visual Basic Upgrade Companion looks for the first assignment to each variable and moves this initialization to the declaration. In this way, the resulting .NET code is more readable and maintainable.

Example: Local Variable Declaration

In this example the initial values for the variables "a", "b" and "c" are moved by the Visual Basic Upgrade Companion to the declaration.

Visual Basic 6.0 code
Private Sub Foo()
    Dim a As Integer
    Dim b As Integer
    Dim c As Integer
    a = 5
    b = 10
    c = b + 5
    MsgBox(c)
End Sub
VB.NET: VB Upgrade Wizard generated code
Private Sub Foo()
    Dim a As Integer
    Dim b As Integer
    Dim c As Integer
    a = 5
    b = 10
    c = b + 5
    MsgBox(c)
End Sub
VB.NET: Visual Basic Upgrade Companion generated code
Private Sub Foo()
    Dim a As Integer = 5
    Dim b As Integer = 10
    Dim c As Integer = b + 5
    MsgBox(CStr(c))
End Sub
C#: Visual Basic Upgrade Companion generated code
void Foo()
    int a = 5;
    int b = 10;
    int c = b + 5;
    MessageBox.Show(c.ToString());
}
Example: Class Variable Declaration

This example shows how the Visual Basic Upgrade Companion removes the method Class_Initialize_Renamed. It is no longer necessary because the initialization of the variable count was moved to its declaration.

Visual Basic 6.0 code (class file)
Private count As Integer
Sub Class_Initialize()
    count = 20
End Sub
Sub IncCount()
    count = count + 1
End Sub
Function GetCount() As Integer
    GetCount = count
End Function 
VB.NET: VB Upgrade Wizard generated code
Friend Class Class1
    Private count As Short
    'UPGRADE_NOTE: Class_Initialize was upgraded to Class_Initialize_Renamed.
    Sub Class_Initialize_Renamed()
        count = 20
    End Sub
    Public Sub New()
        MyBase.New()
        Class_Initialize_Renamed()
    End Sub
    Sub IncCount()
        count = count + 1
    End Sub
    Function GetCount() As Short
        GetCount = count
    End Function
End Class
VB.NET: Visual Basic Upgrade Companion generated code
Friend Class Class1
    Private count As Integer= 20
    Sub IncCount()
        count = count += 1
    End Sub
    Function GetCount() As Integer
        GetCount = count
    End Function
End Class
C#: Visual Basic Upgrade Companion generated code
internal class Class1
    private int count = 20;
    void IncCount()
        count++;
    int GetCount()
        return count;
}