Code Conversion
This section provides some transformation that we apply so that some elements will be upgraded as you need it.

1. GoSub Statements

GoSub statements can be transformed to local functions only when C# is the target language.

1.1. Do not convert Go Sub statements

Choosing this option, the VBUC will not apply any special pattern recognition mechanism. GoSub statements are not supported by default in .NET structured code.
Original VB6 code:
Public Sub Main()
Dim i As Integer
i = 4
If i = 1 Then
GoSub printOne
ElseIf i = 2 Then
GoSub printTwo
ElseIf i = 3 Then
GoSub printThree
Else
GoSub SomethingElse
End If
GoTo exitLabel
printOne:
MsgBox "Value = 1"
Return
printTwo:
MsgBox "Value = 2"
Return
printThree:
MsgBox "Value = 3"
Return
SomethingElse:
MsgBox "Invalid Value!"
Return
exitLabel:
End Sub
C# code:
public static void Main()
{
int i = 4;
if (i == 1)
{
//UPGRADE_ISSUE: (1014) GoSub statement is not supported.
//UPGRADE_TODO: (1065) Error handling statement (Go Sub) could not be converted.
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("GoSub Label (printOne)");
}
else if (i == 2)
{
//UPGRADE_ISSUE: (1014) GoSub statement is not supported.
//UPGRADE_TODO: (1065) Error handling statement (Go Sub) could not be converted.
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("GoSub Label (printTwo)");
}
else if (i == 3)
{
//UPGRADE_ISSUE: (1014) GoSub statement is not supported.
//UPGRADE_TODO: (1065) Error handling statement (Go Sub) could not be converted.
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("GoSub Label (printThree)");
}
else
{
//UPGRADE_ISSUE: (1014) GoSub statement is not supported.
//UPGRADE_TODO: (1065) Error handling statement (Go Sub) could not be converted.
UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("GoSub Label (SomethingElse)");
}
return;
printOne:
MessageBox.Show("Value = 1", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
//UPGRADE_WARNING: (2081) Return has a new behavior.
return;
printTwo:
MessageBox.Show("Value = 2", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
//UPGRADE_WARNING: (2081) Return has a new behavior.
return;
printThree:
MessageBox.Show("Value = 3", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
//UPGRADE_WARNING: (2081) Return has a new behavior.
return;
SomethingElse:
MessageBox.Show("Invalid Value!", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
//UPGRADE_WARNING: (2081) Return has a new behavior.
return;
}

1.2. Convert GoSub statements to C# local function

Choosing this option, the VBUC will apply the special pattern recognition mechanism, to support the GoSub statement. This feature will only be applied when generating C# code.
General Description:
Visual Basic 6.0 provides the ability to jump into the code from one portion to another thru "labels" and create code that is not structured, according to the suggested coding patterns.
However, using GoSub and return statements gives the VB6 programmer certain functionality that used with certain restrictions can create "structured code".
By turning this feature on, the VBUC will recognize some of these patterns and will convert them to local functions for C#.
Original VB6 code:
Public Sub Main()
Dim i As Integer
i = 4
If i = 1 Then
GoSub printOne
ElseIf i = 2 Then
GoSub printTwo
ElseIf i = 3 Then
GoSub printThree
Else
GoSub SomethingElse
End If
GoTo exitLabel
printOne:
MsgBox "Value = 1"
Return
printTwo:
MsgBox "Value = 2"
Return
printThree:
MsgBox "Value = 3"
Return
SomethingElse:
MsgBox "Invalid Value!"
Return
exitLabel:
End Sub
C# code:
public static void Main()
{
int i = 4;
if (i == 1)
{
printOne();
}
else if (i == 2)
{
printTwo();
}
else if (i == 3)
{
printThree();
}
else
{
SomethingElse();
}
return;
void printOne()
{
MessageBox.Show("Value = 1", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
void printTwo()
{
MessageBox.Show("Value = 2", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
void printThree()
{
MessageBox.Show("Value = 3", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
void SomethingElse()
{
MessageBox.Show("Invalid Value!", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
}

2. ActiveX

2.1. .NET Assemblies with COM Visible

This option will generate special attributes for the converted classes and their members in order to keep the resulting assemblies exposed through a COM interface.
This feature enables the resulting .NET components to be called from other non-managed components or applications via COM.
General Description:
The VBUC converts Visual Basic 6 ActiveX binaries to .NET assemblies. By default, the resulting assemblies can be used only from managed code. This option should be selected to generate the .NET attributes required to expose these assemblies as COM Objects if it’s necessary to use them from non-managed code.
In addition to the “COMVisible” attribute on the class members, the resulting project is also marked as COM Visible.
COM-Visible option
Original VB6 code:
Code declared in an Activex EXE:
Module1.bas
Public myVar As String
Customer.cls
Attribute VB_Name = "Customer"
Private g_TheNumber As Integer
Public Property Let TheNumber(ByVal new_value As Integer)
g_TheNumber = new_value
End Property
Public Property Get TheNumber() As Integer
TheNumber = g_TheNumber
End Property
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub Form_Load()
Set m_Customer1 = New ExeBillingObjects.Customer
Set m_Customer2 = New ExeBillingObjects.Customer
End Sub
Private Sub cmdGet_Click()
txtTheNumber.Text = m_Customer1.TheNumber
End Sub
C# code:
Code declared in an Activex EXE:
Module1.cs
internal static class Module1
{
public static string myVar = "";
}
Customer.cs
[ComVisible(true)][ProgId("ExeBillingObjects.Customer")][ClassInterface(ClassInterfaceType.AutoDual)]
public class Customer
{
public int TheNumber
{
get
{
return Module1.g_TheNumber;
}
set
{
Module1.g_TheNumber = value;
}
}
}
Code located in the main application that uses the Activex EXE:
private ExeBillingObjects.Customer m_Customer1 = null;
private ExeBillingObjects.Customer m_Customer2 = null;
private void cmdSet_Click( Object eventSender, EventArgs eventArgs)
{
m_Customer1.TheNumber = Convert.ToInt32(Double.Parse(txtTheNumber.Text));
txtTheNumber.Text = "";
}
private void Form1_Load( Object eventSender, EventArgs eventArgs)
{
m_Customer1 = new ExeBillingObjects.Customer();
m_Customer2 = new ExeBillingObjects.Customer();
}
VB.NET code:
Code declared in an Activex EXE:
Module1.vb
Module Module1
Public myVar As String = ""
End Module
Customer.vb
<ComVisible(True)> _
<ProgId("ExeBillingObjects.Customer")> _
<ClassInterface(ClassInterfaceType.AutoDual)> _
Public Class Customer
Public Property TheNumber() As Integer
Get
Return g_TheNumber
End Get
Set(ByVal Value As Integer)
g_TheNumber = Value
End Set
End Property
End Class
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub cmdGet_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles cmdGet.Click
txtTheNumber.Text = CStr(m_Customer1.TheNumber)
End Sub
Private Sub Form1_Load(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles MyBase.Load
m_Customer1 = New ExeBillingObjects.Customer()
m_Customer2 = New ExeBillingObjects.Customer()
End Sub

2.2. Out process and Application

This optional feature enables the conversion of ActiveX DLLs and EXEs (with global variables in a .bas module) via a helper class (ComponentClassHelper) that controls the instantiation of the generated classes.
  • ActiveX EXEs are converted to out-of-process .NET EXEs.
  • ActiveX DLLs are converted to .NET class libraries using application domains.
  • Component instantiation is performed using helper classes. With this approach most of the ActiveX functionality is replicated in the converted code.
General Description:
The VBUC converts Visual Basic 6 ActiveX EXEs to .NET EXE projects (out-of-process) and ActiveX DLLs to .NET assemblies (class library projects).
One of the main differences between Visual Basic 6 ActiveX binaries and .NET assemblies is how the components are instantiated and how their initialization determines its lifetime behavior.
When this feature is active, a helper class is used to replicate the following ActiveX instantiation types:
  • Private
  • PublicNotCreatable
  • SingleUse
  • GlobalSingleUse
  • MultiUse
  • GlobalMultiUse
Original VB6 code:
Code declared in an Activex EXE:
Module1.bas
Public myVar As String
Customer.cls
Attribute VB_Name = "Customer"
Private g_TheNumber As Integer
Public Property Let TheNumber(ByVal new_value As Integer)
g_TheNumber = new_value
End Property
Public Property Get TheNumber() As Integer
TheNumber = g_TheNumber
End Property
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub Form_Load()
Set m_Customer1 = New ExeBillingObjects.Customer
Set m_Customer2 = New ExeBillingObjects.Customer
End Sub
Private Sub cmdGet_Click()
txtTheNumber.Text = m_Customer1.TheNumber
End Sub
C# code:
Code declared in an Activex EXE:
Module1.cs
internal static class Module1
{
public static string myVar = "";
internal static void InitGlobalVars()
{
myVar = "";
}
}
Customer.cs
public class Customer : UpgradeHelpers.Activex.ComponentClassHelper
{
public int TheNumber
{
get
{
return g_TheNumber;
}
set
{
g_TheNumber = value;
}
}
}
Code located in the main application that uses the Activex EXE:
private ExeBillingObjects.Customer m_Customer1 = null;
private ExeBillingObjects.Customer m_Customer2 = null;
private void cmdGet_Click( Object eventSender, EventArgs eventArgs)
{
txtTheNumber.Text = Convert.ToString(m_Customer1.TheNumber);
}
private void Form1_Load( Object eventSender, EventArgs eventArgs)
{
m_Customer1 = ExeBillingObjects.ExeBillingObjectsFactory.Create <ExeBillingObjects.Customer>(m_Customer1);
m_Customer2 = ExeBillingObjects.ExeBillingObjectsFactory.Create <ExeBillingObjects.Customer>(m_Customer2);
VB.NET code:
Code declared in an Activex EXE:
Module1.vb
Module Module1
Public myVar As String = ""
Public Sub InitGlobalVars()
myVar = ""
End Sub
End Module
Customer.vb
Public Class Customer Inherits UpgradeHelpers.Activex.ComponentClassHelper
Public Property TheNumber() As Integer
Get
Return g_TheNumber
End Get
Set(ByVal Value As Integer)
g_TheNumber = Value
End Set
End Property
End Class
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub cmdGet_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles cmdGet.Click
txtTheNumber.Text = CStr(m_Customer1.TheNumber)
End Sub
Private Sub Form1_Load(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles MyBase.Load
m_Customer1 = ExeBillingObjects.ExeBillingObjectsFactory.Create(Of ExeBillingObjects.Customer)(m_Customer1)
m_Customer2 = ExeBillingObjects.ExeBillingObjectsFactory.Create(Of ExeBillingObjects.Customer)(m_Customer2)
End Sub

2.3. Standard .NET Assemblies

This optional feature converts the ActiveX DLLs and EXEs to .NET class libraries (DLLs).
  • All ActiveX binaries are converted to native .NET assemblies (class libraries).
  • With this approach, the converted code can be used only from managed code and the different ActiveX instantiation models (e.g MultiUse, GlobalMultiuse, etc) won’t be supported.
General Description:
The VBUC converts Visual Basic 6 ActiveX EXEs and ActiveX DLLs to .NET class libraries (DLLs).
One of the main differences between Visual Basic 6 ActiveX binaries and .NET assemblies is how the components are instantiated and how their initialization determines its lifetime behavior.
With this option switched on, the code is converted to pure .NET code and the ActiveX instantiation models won’t be supported.
Original VB6 code:
Code declared in an Activex EXE:
Module1.bas
Public myVar As String
Customer.cls
Attribute VB_Name = "Customer"
Private g_TheNumber As Integer
Public Property Let TheNumber(ByVal new_value As Integer)
g_TheNumber = new_value
End Property
Public Property Get TheNumber() As Integer
TheNumber = g_TheNumber
End Property
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub Form_Load()
Set m_Customer1 = New ExeBillingObjects.Customer
Set m_Customer2 = New ExeBillingObjects.Customer
End Sub
Private Sub cmdGet_Click()
txtTheNumber.Text = m_Customer1.TheNumber
End Sub
C# code:
Code declared in an Activex EXE:
Module1.cs
internal static class Module1
{
public static string myVar = "";
}
Customer.cs
public class Customer
{
public int TheNumber
{
get
{
return g_TheNumber;
}
set
{
g_TheNumber = value;
}
}
}
Code located in the main application that uses the Activex EXE:
private ExeBillingObjects.Customer m_Customer1 = null;
private ExeBillingObjects.Customer m_Customer2 = null;
private void cmdGet_Click( Object eventSender, EventArgs eventArgs)
{
txtTheNumber.Text = m_Customer1.TheNumber.ToString();
}
private void Form1_Load( Object eventSender, EventArgs eventArgs)
{
m_Customer1 = new ExeBillingObjects.Customer();
m_Customer2 = new ExeBillingObjects.Customer();
}
VB.NET code:
Code declared in an Activex EXE:
Module1.vb
Module Module1
Public myVar As String = ""
End Module
Customer.vb
Public Class Customer
Public Property TheNumber() As Integer
Get
Return g_TheNumber
End Get
Set(ByVal Value As Integer)
g_TheNumber = Value
End Set
End Property
End Class
Code located in the main application that uses the Activex EXE:
Private m_Customer1 As ExeBillingObjects.Customer
Private m_Customer2 As ExeBillingObjects.Customer
Private Sub cmdGet_Click(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles cmdGet.Click
txtTheNumber.Text = CStr(m_Customer1.TheNumber)
End Sub
Private Sub Form1_Load(ByVal eventSender As Object, ByVal eventArgs As EventArgs) Handles MyBase.Load
m_Customer1 = New ExeBillingObjects.Customer()
m_Customer2 = New ExeBillingObjects.Customer()
End Sub

3. Generate Auto Implemented Properties

3.1. On

Auto-Implemented Properties will be generated when the original VB6 properties follow the basic standard pattern.
This feature verifies if there is a property defined on a local private field (both shares the same type) and it removes the field declarations and just leaves an auto-implemented property, replacing any reference to the field with a reference to the property in the class.
This feature is available for C# only.
Original VB6 code:
Private IntVar As Integer
Private BoolVar As Boolean
Private StrVar As String
Public Property Let IntVarProp(value As Integer)
'some comments for IntVarProp property header'
IntVar = value
'some comments for IntVarProp property footer'
End Property
Public Property Get IntVarProp() As Integer
'some comments for IntVarProp property header'
IntVarProp = IntVar
'some comments for IntVarProp property footer'
End Property
Public Property Let BoolVarProp(value As Boolean)
BoolVar = value
End Property
Public Property Get BoolVarProp() As Boolean
BoolVarProp = BoolVar
End Property
Public Property Let StrVarProp(value As String)
StrVar = value
End Property
Public Property Get StrVarProp() As String
StrVarProp = StrVar
End Property
Public Sub FieldsUsage()
IntVar = 0
BoolVar = False
StrVar = "Hello World"
parameterFieldsUsage IntVar, BoolVar, StrVar
End Sub
Public Sub PropertiesUsage()
IntVarProp = 0
BoolVarProp = False
StrVarProp = "Hello World"
parameterProperiesUsage IntVarProp, BoolVarProp, StrVarProp
End Sub
Public Sub parameterFieldsUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
''
End Sub
Public Sub parameterProperiesUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
''
End Sub
C# code:
public int IntVarProp
{
//some comments for IntVarProp property header
get;
//some comments for IntVarProp property footer
//some comments for IntVarProp property header
set;
//some comments for IntVarProp property footer
}
public bool BoolVarProp
{
get;
set;
}
public string StrVarProp
{
get;
set;
}
public void FieldsUsage()
{
this.IntVarProp = 0;
this.BoolVarProp = false;
this.StrVarProp = "Hello World";
parameterFieldsUsage(this.IntVarProp, this.BoolVarProp, this.StrVarProp);
}
public void PropertiesUsage()
{
IntVarProp = 0;
BoolVarProp = false;
StrVarProp = "Hello World";
parameterProperiesUsage(IntVarProp, BoolVarProp, StrVarProp);
}
public void parameterFieldsUsage(int IntVar, bool BoolVar, string StrVar)
{
//
}
public void parameterProperiesUsage(int IntVar, bool BoolVar, string StrVar)
{
//
}

3.2. Off

No Auto-Implemented Properties will be generated from the original VB6 ones.
Original VB6 code:
Private IntVar As Integer
Private BoolVar As Boolean
Private StrVar As String
Public Property Let IntVarProp(value As Integer)
'some comments for IntVarProp property header'
IntVar = value
'some comments for IntVarProp property footer'
End Property
Public Property Get IntVarProp() As Integer
'some comments for IntVarProp property header'
IntVarProp = IntVar
'some comments for IntVarProp property footer'
End Property
Public Property Let BoolVarProp(value As Boolean)
BoolVar = value
End Property
Public Property Get BoolVarProp() As Boolean
BoolVarProp = BoolVar
End Property
Public Property Let StrVarProp(value As String)
StrVar = value
End Property
Public Property Get StrVarProp() As String
StrVarProp = StrVar
End Property
Public Sub FieldsUsage()
IntVar = 0
BoolVar = False
StrVar = "Hello World"
parameterFieldsUsage IntVar, BoolVar, StrVar
End Sub
Public Sub PropertiesUsage()
IntVarProp = 0
BoolVarProp = False
StrVarProp = "Hello World"
parameterProperiesUsage IntVarProp, BoolVarProp, StrVarProp
End Sub
Public Sub parameterFieldsUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
''
End Sub
Public Sub parameterProperiesUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
''
End Sub
C# code:
private int IntVar = 0;
private bool BoolVar = false;
private string StrVar = "";
public int IntVarProp
{
get
{
//some comments for IntVarProp property header
return IntVar;
//some comments for IntVarProp property footer
}
set
{
//some comments for IntVarProp property header
IntVar = value;
//some comments for IntVarProp property footer
}
}
public bool BoolVarProp
{
get
{
return BoolVar;
}
set
{
BoolVar = value;
}
}
public string StrVarProp
{
get
{
return StrVar;
}
set
{
StrVar = value;
}
}
public void FieldsUsage()
{
IntVar = 0;
BoolVar = false;
StrVar = "Hello World";
parameterFieldsUsage(IntVar, BoolVar, StrVar);
}
public void PropertiesUsage()
{
IntVarProp = 0;
BoolVarProp = false;
StrVarProp = "Hello World";
parameterProperiesUsage(IntVarProp, BoolVarProp, StrVarProp);
}
public void parameterFieldsUsage(int IntVar, bool BoolVar, string StrVar)
{
//
}
public void parameterProperiesUsage(int IntVar, bool BoolVar, string StrVar)
{
//
}

4. Comment Out Dead Code

4.1. On

Private methods that are not referenced will be commented out.
Original VB6 code:
Public Sub PublicMethod()
Call CalledPrivateMethod
End Sub
Private Sub CalledPrivateMethod()
MsgBox "This method is called."
End Sub
Private Sub UncalledPrivateMethod()
MsgBox "This method is not called."
End Sub
C# code:
public void PublicMethod()
{
CalledPrivateMethod();
}
private void CalledPrivateMethod()
{
MessageBox.Show("This method is called.", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
//UPGRADE_NOTE: (7001) The following declaration (UncalledPrivateMethod) seems to be dead code
//private void UncalledPrivateMethod()
//{
//MessageBox.Show("This method is not called.", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
//}
VB.NET code:
Public Sub PublicMethod()
CalledPrivateMethod()
End Sub
Private Sub CalledPrivateMethod()
MessageBox.Show("This method is called.", My.Application.Info.Title)
End Sub
'UPGRADE_NOTE: (7001) The following declaration (UncalledPrivateMethod) seems to be dead code'
'Private Sub UncalledPrivateMethod()'
'MessageBox.Show("This method is not called.", My.Application.Info.Title)'
'End Sub'

4.1. Off

This feature will be turned off and no changes pertaining to this feature will be made.
Original VB6 code:
Public Sub PublicMethod()
Call CalledPrivateMethod
End Sub
Private Sub CalledPrivateMethod()
MsgBox "This method is called."
End Sub
Private Sub UncalledPrivateMethod()
MsgBox "This method is not called."
End Sub
C# code:
public void PublicMethod()
{
CalledPrivateMethod();
}
private void CalledPrivateMethod()
{
MessageBox.Show("This method is called.", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
private void UncalledPrivateMethod()
{
MessageBox.Show("This method is not called.", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
}
VB.NET code:
Public Sub PublicMethod()
CalledPrivateMethod()
End Sub
Private Sub CalledPrivateMethod()
MessageBox.Show("This method is called.", My.Application.Info.Title)
End Sub
Private Sub UncalledPrivateMethod()
MessageBox.Show("This method is not called.", My.Application.Info.Title)
End Sub

5. Default Property Resolution

5.1. Static code analysis and helpers classes

By switching this feature on, the majority of default property cases that could not be resolved with a static code analysis are managed at runtime by the use of a helper class.
  • Manages special cases of default properties at runtime by using a helper class.
  • Increases the automation ratio and reduces the manual effort required to achieve functional equivalence.
General Description:
The Visual Basic Upgrade Companion uses a powerful static code analyzer to determine the correct type for each object. By having the correct type for each object, the VBUC is able to determine its default property and expand this property in the converted code.
However, there are some cases where it’s not possible to determine the type of an object by using this technique. For these scenarios, the VBUC provides a helper class that is able to determine the type of these objects at runtime and get or set their default property.
In the following example, the variable ctl is used to iterate over a different type of controls. Each of these controls has different default properties, thus, during runtime, the default property of ctl will change. If this example is converted using this option, the helper class will determine the type of each use of the ctl variable at runtime and will get the appropriate default property for each instance.
Original VB6 code:
Dim s As String
'Display the default property of controls of a Form'
For Each ctl In Me.Controls
s = ctl
MsgBox s
Next ctl
'Display the default property of TextBox'
MsgBox Me.TextBox1
C# code:
string s = String.Empty;
//Display the default property of controls of a Form
foreach (Control ctl in ContainerHelper.Controls(this))
{
s = ReflectionHelper.GetPrimitiveValue(ctl).ToString();
MessageBox.Show(s, Application.ProductName);
}
//Display the default property of TextBox
MessageBox.Show(this.TextBox1.Text, Application.ProductName);
VB.NET code:
Dim s As String = ""
'Display the default property of controls of a Form'
For Each ctl As Control In ContainerHelper.Controls(Me)
s = ReflectionHelper.GetPrimitiveValue(ctl).ToString()
MessageBox.Show(s, Application.ProductName)
Next ctl
'Display the default property of TextBox'
MessageBox.Show(Me.TextBox1.Text, Application.ProductName)

5.1. Static code analysis only

By switching this feature on, the VBUC will use a powerful static code analysis process to determine the correct type for each object and expands its default property.
  • Expands the default properties by using only static code analysis.
  • There are some cases where it’s not possible to determine the type of an object by using static code analysis and it may require manual intervention to achieve functional equivalence.
General Description:
The Visual Basic Upgrade Companion (VBUC) uses a static code analysis process to infer/determine the correct type for each object. By having the correct type of each object, the VBUC can determine the default property of the object and expand this property in the converted code.
However, there some cases where it is not possible to determine the type of an object by using a static code analysis. For these cases manual changes are required to achieve functional equivalence.
Original VB6 code:
Dim s As String
'Display the default property of controls of a Form'
For Each ctl In Me.Controls
s = ctl
MsgBox s
Next ctl
'Display the default property of TextBox'
MsgBox Me.TextBox1
C# code:
string s = String.Empty;
//Display the default property of controls of a Form
foreach (Control ctl in ContainerHelper.Controls(this))
{
//UPGRADE_WARNING: (1068) ctl of type VB.Control is being forced to string
s = ctl.ToString();
MessageBox.Show(s, Application.ProductName);
}
//Display the default property of TextBox
MessageBox.Show(this.TextBox1.Text, Application.ProductName);
VB.NET code:
Dim s As String = ""
'Display the default property of controls of a Form'
For Each ctl As Control In ContainerHelper.Controls(Me)
'UPGRADE_WARNING: (1068) ctl of type VB.Control is being forced to String.'
s = ctl.ToString()
MessageBox.Show(s, Application.ProductName)
Next ctl
'Display the default property of TextBox'
MessageBox.Show(Me.TextBox1.Text, Application.ProductName)

6. Error Handling

6.1. Leave on Error Statements (VB.NET Only)

By choosing this option the VBUC will generate .NET source code that employs the “On Error” statements just like the Visual Basic 6 code.
  • This option increases the automation and reduces the manual effort required to get functional equivalence.
  • This feature is optional while upgrading to Visual Basic .NET but is not available for C#.
General Description:
The “On Error Go To” and “On Error Resume Next” error handling statements present in the Visual Basic 6 code will remain the same on the Visual Basic .NET output code. This feature removes the need for manual changes to bring the error handling statements to functional equivalence since it will be used the same in the upgraded code.
Original VB6 code:
Public Sub OnErrorGotoLabelMethod(arg As String)
On Error GoTo errHnd
Dim s As Integer
s = CInt(arg)
Foo s
Exit Sub
errHnd: