Generated Code
In the following section, will find the generated code (C# and VB.NET), important messages after upgrading your code (EWIs), and helpers information.

What does the VBUC generate? - C# and VB.NET Differences

There are some features that help to simulate VB6 behavior, making C# easier to use, but in some cases, VB.NET could be better. In this section, you will see a comparison of some features in C# and VB.NET.

Error Handling

It refers to the response and recovery procedures from error conditions present in a software application. The VBUC offers three options for error handling:
    1.
      "On Error GoTo" and "On Error Resume Next" statements will remain the same code in the VB.NET output code.
    2.
      Most patterns will be upgraded to Try-Catch blocks. This option covers a huge amount of "On Error GoTo" patterns and very basic cases of "On Error Resume Next".
    3.
      This feature covers the most common patterns of "On Error GoTo" and will generate special patterns to support most "On Error Resume Next" patterns.

Original VB6 Code:

1
Public Sub OnErrorGotoLabelMethod(arg As String)
2
On Error GoTo errHnd
3
Dim s As Integer
4
s = CInt(arg)
5
Foo s
6
Exit Sub
7
errHnd:
8
MsgBox "Invalid Argument"
9
End Sub
10
11
Public Sub OnErrorResumeNextMethod(arg As String)
12
On Error Resume Next
13
MsgBox arg
14
MsgBox CInt(arg)
15
MsgBox "This line will be executed allways"
16
17
If Err.Number <> 0 Then
18
'This code should be executed if there were any error(s)
19
MsgBox "OnErrorResumeNextMethod reached the last statement"
20
MsgBox "OnErrorResumeNextMethod reached the last statement"
21
MsgBox "OnErrorResumeNextMethod reached the last statement"
22
End If
23
End Sub
Copied!

Leave On Error Statements (VB.NET Only)

1
Public Sub OnErrorGotoLabelMethod(ByVal arg As String)
2
On Error GoTo errHnd
3
Dim s As Integer
4
s = CInt(arg)
5
Foo(s)
6
Exit Sub
7
errHnd:
8
MessageBox.Show("Invalid Argument", My.Application.Info.Title)
9
End Sub
10
11
Public Sub OnErrorResumeNextMethod(ByVal arg As String)
12
On Error Resume Next
13
MessageBox.Show(arg, My.Application.Info.Title)
14
MessageBox.Show(CStr(CInt(arg)), My.Application.Info.Title)
15
MessageBox.Show("This line will be executed allways", My.Application.Info.Title)
16
17
If Information.Err().Number <> 0 Then
18
'This code should be executed if there were any error(s)
19
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
20
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
21
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
22
End If
23
End Sub
Copied!

Convert To Try-Catch

C# Code:
1
public void OnErrorGotoLabelMethod(string arg)
2
{
3
try
4
{
5
int s = 0;
6
s = Convert.ToInt32(Double.Parse(arg));
7
Foo(s);
8
}
9
catch
10
{
11
MessageBox.Show("Invalid Argument", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
12
}
13
}
14
15
public void OnErrorResumeNextMethod(string arg)
16
{
17
//UPGRADE_TODO: (1069) Error handling statement (On Error Resume Next) was converted to a pattern that might have a different behavior.
18
try
19
{
20
MessageBox.Show(arg, AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
21
MessageBox.Show(Convert.ToInt32(Double.Parse(arg)).ToString(), AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
22
MessageBox.Show("This line will be executed allways", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
23
24
//UPGRADE_WARNING: (2081) Err.Number has a new behavior.
25
if (Information.Err().Number != 0)
26
{
27
//This code should be executed if there were any error(s)
28
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
29
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
30
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
31
}
32
}
33
catch (Exception exc)
34
{
35
NotUpgradedHelper.NotifyNotUpgradedElement("Resume in On-Error-Resume-Next Block");
36
}
37
}
Copied!
VB.NET Code:
1
Public Sub OnErrorGotoLabelMethod(ByVal arg As String)
2
Try
3
Dim s As Integer
4
s = CInt(arg)
5
Foo(s)
6
7
Catch
8
MessageBox.Show("Invalid Argument", My.Application.Info.Title)
9
End Try
10
End Sub
11
12
Public Sub OnErrorResumeNextMethod(ByVal arg As String)
13
'UPGRADE_TODO: (1069) Error handling statement (On Error Resume Next) was converted to a pattern that might have a different behavior.'
14
Try
15
MessageBox.Show(arg, My.Application.Info.Title)
16
MessageBox.Show(CStr(CInt(arg)), My.Application.Info.Title)
17
MessageBox.Show("This line will be executed allways", My.Application.Info.Title)
18
19
If Information.Err().Number <> 0 Then
20
'This code should be executed if there were any error(s)'
21
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
22
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
23
MessageBox.Show("OnErrorResumeNextMethod reached the last statement", My.Application.Info.Title)
24
End If
25
Catch exc As Exception
26
NotUpgradedHelper.NotifyNotUpgradedElement("Resume in On-Error-Resume-Next Block")
27
End Try
28
End Sub
Copied!

To Try-Catch With Lambdas (C# Only)

1
public void OnErrorGotoLabelMethod(string arg)
2
{
3
try
4
{
5
int s = 0;
6
s = Convert.ToInt32(Double.Parse(arg));
7
Foo(s);
8
}
9
catch
10
{
11
MessageBox.Show("Invalid Argument", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
12
}
13
}
14
15
public void OnErrorResumeNextMethod(string arg)
16
{
17
Exception ex = null;
18
ErrorHandlingHelper.ResumeNext(out ex,
19
() => {MessageBox.Show(arg, AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));},
20
() => {MessageBox.Show(Convert.ToInt32(Double.Parse(arg)).ToString(), AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));},
21
() => {MessageBox.Show("This line will be executed allways", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));});
22
if (ex != null)
23
{
24
ErrorHandlingHelper.ResumeNext(
25
//This code should be executed if there were any error(s)
26
() => {MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));},
27
() => {MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));},
28
() => {MessageBox.Show("OnErrorResumeNextMethod reached the last statement", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));});
29
}
30
}
Copied!

Late Binding

This is a mechanism where the type is unknown until the variable is used during runtime; usually through the assignment. The VBUC offers three options for late binding:
    1.
      This option will cause the late binding access cases that could not be resolved with a static code analysis to be managed at runtime by means of a helper class.
    2.
      VBUC will use its static code analysis process to determine the correct type for each object and resolve the late binding access. Note: The Visual Basic Upgrade Companion solves most of these issues by using a static code analysis process to infer and determine the correct data type for each variable. However, there are some variables that take several values with inconsistent types and there is no way to infer a proper type. For these cases, manual changes are required to reach functional equivalence.
    3.
      This option will cause the late binding access cases that could not be resolved with a static code analysis to be managed at runtime with dynamic variables.

Original VB6 Code:

1
Public Sub Func(myControl As Control, myForm As Form, myVar As Variant)
2
myControl.controlProp1 = myVar.varProp1
3
myForm.formProp1 = myControl.controlProp1
4
myVar.varProp1 = myForm.formProp1
5
6
myControl.Func 1
7
myForm.Func 1
8
myVar.Func 1
9
End Sub
Copied!

Static code analysis + helper classes

C# Code:
1
public void Func(Control myControl, Form myForm, object myVar)
2
{
3
ReflectionHelper.LetMember(myControl, "controlProp1", ReflectionHelper.GetMember<object>(myVar, "varProp1"));
4
ReflectionHelper.LetMember(myForm, "formProp1", ReflectionHelper.GetMember<object>(myControl, "controlProp1"));
5
ReflectionHelper.LetMember(myVar, "varProp1", ReflectionHelper.GetMember<object>(myForm, "formProp1"));
6
7
ReflectionHelper.Invoke(myControl, "Func", new object[]{1});
8
ReflectionHelper.Invoke(myForm, "Func", new object[]{1});
9
ReflectionHelper.Invoke(myVar, "Func", new object[]{1});
10
}
Copied!
VB.NET Code:
1
Public Sub Func(ByVal myControl As Control, ByVal myForm As Form, ByVal myVar As Object)
2
ReflectionHelper.LetMember(myControl, "controlProp1", ReflectionHelper.GetMember(myVar, "varProp1"))
3
ReflectionHelper.LetMember(myForm, "formProp1", ReflectionHelper.GetMember(myControl, "controlProp1"))
4
ReflectionHelper.LetMember(myVar, "varProp1", ReflectionHelper.GetMember(myForm, "formProp1"))
5
6
ReflectionHelper.Invoke(myControl, "Func", New Object() {1})
7
ReflectionHelper.Invoke(myForm, "Func", New Object() {1})
8
ReflectionHelper.Invoke(myVar, "Func", New Object() {1})
9
End Sub
Copied!

Static code analysis only

C# Code:
1
public void Func(Control myControl, Form myForm, object myVar)
2
{
3
//UPGRADE_TODO: (1067) Member controlProp1 is not defined in type VB.Control.
4
//UPGRADE_TODO: (1067) Member varProp1 is not defined in type Variant.
5
myControl.controlProp1 = myVar.varProp1;
6
//UPGRADE_TODO: (1067) Member formProp1 is not defined in type VB.Form.
7
//UPGRADE_TODO: (1067) Member controlProp1 is not defined in type VB.Control.
8
myForm.formProp1 = myControl.controlProp1;
9
//UPGRADE_TODO: (1067) Member varProp1 is not defined in type Variant.
10
//UPGRADE_TODO: (1067) Member formProp1 is not defined in type VB.Form.
11
myVar.varProp1 = myForm.formProp1;
12
13
//UPGRADE_TODO: (1067) Member Func is not defined in type VB.Control.
14
myControl.Func(1);
15
//UPGRADE_TODO: (1067) Member Func is not defined in type VB.Form.
16
myForm.Func(1);
17
//UPGRADE_TODO: (1067) Member Func is not defined in type Variant.
18
myVar.Func(1);
19
}
Copied!
VB.NET Code:
1
Public Sub Func(ByVal myControl As Control, ByVal myForm As Form, ByVal myVar As Object)
2
'UPGRADE_TODO: (1067) Member controlProp1 is not defined in type VB.Control.'
3
'UPGRADE_TODO: (1067) Member varProp1 is not defined in type Variant.'
4
myControl.controlProp1 = myVar.varProp1
5
'UPGRADE_TODO: (1067) Member formProp1 is not defined in type VB.Form.'
6
'UPGRADE_TODO: (1067) Member controlProp1 is not defined in type VB.Control.'
7
myForm.formProp1 = myControl.controlProp1
8
'UPGRADE_TODO: (1067) Member varProp1 is not defined in type Variant.'
9
'UPGRADE_TODO: (1067) Member formProp1 is not defined in type VB.Form.'
10
myVar.varProp1 = myForm.formProp1
11
12
'UPGRADE_TODO: (1067) Member Func is not defined in type VB.Control.'
13
myControl.Func(1)
14
'UPGRADE_TODO: (1067) Member Func is not defined in type VB.Form.'
15
myForm.Func(1)
16
'UPGRADE_TODO: (1067) Member Func is not defined in type Variant.'
17
myVar.Func(1)
18
End Sub
Copied!

Static code analysis + dynamic variables

C# Code:
1
public void Func(Control myControl, Form myForm, object myVar)
2
{
3
((dynamic) myControl).controlProp1 = ((dynamic) myVar).varProp1;
4
((dynamic) myForm).formProp1 = ((dynamic) myControl).controlProp1;
5
((dynamic) myVar).varProp1 = ((dynamic) myForm).formProp1;
6
7
((dynamic) myControl).Func(1);
8
((dynamic) myForm).Func(1);
9
((dynamic) myVar).Func(1);
10
}
Copied!
VB.NET Code:
1
Option Strict Off
2
3
Public Sub Func(ByVal myControl As Control, ByVal myForm As Form, ByVal myVar As Object)
4
CType(myControl, object).controlProp1 = myVar.varProp1
5
CType(myForm, object).formProp1 = CType(myControl, object).controlProp1
6
myVar.varProp1 = CType(myForm, object).formProp1
7
8
CType(myControl, object).Func(1)
9
CType(myForm, object).Func(1)
10
myVar.Func(1)
11
End Sub
Copied!

Go Sub

VB6 provides the ability to jump around in the code from one portion to another thru "labels" and create code that is not structured. By default Go Sub statements are not supported in .NET, but by turning on this option, the VBUC will apply the special pattern recognition mechanism to support the GoSub Statement.
This feature works only for C#. The user can enable or disable it.

Original VB6 Code:

1
Public Sub Main()
2
3
Dim i As Integer
4
i = 4
5
If i = 1 Then
6
GoSub printOne
7
ElseIf i = 2 Then
8
GoSub printTwo
9
ElseIf i = 3 Then
10
GoSub printThree
11
Else
12
GoSub SomethingElse
13
End If
14
GoTo exitLabel
15
16
printOne:
17
MsgBox "Value = 1"
18
Return
19
20
printTwo:
21
MsgBox "Value = 2"
22
Return
23
24
printThree:
25
MsgBox "Value = 3"
26
Return
27
28
SomethingElse:
29
MsgBox "Invalid Value!"
30
Return
31
32
exitLabel:
33
34
End Sub
Copied!

C# Code:

1
public static void Main()
2
{
3
int i = 4;
4
if (i == 1)
5
{
6
printOne();
7
}
8
else if (i == 2)
9
{
10
printTwo();
11
}
12
else if (i == 3)
13
{
14
printThree();
15
}
16
else
17
{
18
SomethingElse();
19
}
20
return;
21
22
void printOne()
23
{
24
MessageBox.Show("Value = 1", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
25
}
26
27
void printTwo()
28
{
29
MessageBox.Show("Value = 2", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
30
}
31
32
void printThree()
33
{
34
MessageBox.Show("Value = 3", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
35
}
36
37
void SomethingElse()
38
{
39
MessageBox.Show("Invalid Value!", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
40
}
41
}
Copied!

VB.NET Code:

1
Public Sub Main()
2
Dim i As Integer = 4
3
If i = 1 Then
4
'UPGRADE_ISSUE: (1014) GoSub statement is not supported. '
5
GoSub printOne
6
ElseIf i = 2 Then
7
'UPGRADE_ISSUE: (1014) GoSub statement is not supported. '
8
GoSub printTwo
9
ElseIf i = 3 Then
10
'UPGRADE_ISSUE: (1014) GoSub statement is not supported. '
11
GoSub printThree
12
Else
13
'UPGRADE_ISSUE: (1014) GoSub statement is not supported. '
14
GoSub SomethingElse
15
End If
16
Exit Sub
17
18
printOne:
19
MessageBox.Show("Value = 1", My.Application.Info.Title)
20
'UPGRADE_WARNING: (2081) Return has a new behavior. '
21
Return
22
23
printTwo:
24
MessageBox.Show("Value = 2", My.Application.Info.Title)
25
'UPGRADE_WARNING: (2081) Return has a new behavior. '
26
Return
27
28
printThree:
29
MessageBox.Show("Value = 3", My.Application.Info.Title)
30
'UPGRADE_WARNING: (2081) Return has a new behavior. '
31
Return
32
33
SomethingElse:
34
MessageBox.Show("Invalid Value!", My.Application.Info.Title)
35
'UPGRADE_WARNING: (2081) Return has a new behavior. '
36
Return
37
End Sub
Copied!

Getting information from the AssemblyInfo file

This feature refers to how the VBUC tool obtains the information contained in the AssemblyInfo file.

Original VB6 Code:

1
Private Sub Form_Load()
2
MsgBox "Hello World!"
3
End
4
End Sub
Copied!

C# Code:

1
private void Form_Load()
2
{
3
MessageBox.Show("Hello World!", AssemblyHelper.GetTitle(System.Reflection.Assembly.GetExecutingAssembly()));
4
Environment.Exit(0);
5
}
Copied!

VB.NET Code:

1
Private Sub Form_Load()
2
MessageBox.Show("Hello World!", My.Application.Info.Title)
3
Environment.Exit(0)
4
End Sub
Copied!

Auto-Implemented Properties

They are used when no additional logic is required in the property accessors, making them more concise and readable.
This feature only works for C#. The user can enable or disable it.

Original VB6 Code:

1
Private IntVar As Integer
2
Private BoolVar As Boolean
3
Private StrVar As String
4
5
Public Property Let IntVarProp(value As Integer)
6
'some comments for IntVarProp property header'
7
IntVar = value
8
'some comments for IntVarProp property footer'
9
End Property
10
Public Property Get IntVarProp() As Integer
11
'some comments for IntVarProp property header'
12
IntVarProp = IntVar
13
'some comments for IntVarProp property footer'
14
End Property
15
Public Property Let BoolVarProp(value As Boolean)
16
BoolVar = value
17
End Property
18
Public Property Get BoolVarProp() As Boolean
19
BoolVarProp = BoolVar
20
End Property
21
Public Property Let StrVarProp(value As String)
22
StrVar = value
23
End Property
24
Public Property Get StrVarProp() As String
25
StrVarProp = StrVar
26
End Property
27
28
Public Sub FieldsUsage()
29
IntVar = 0
30
BoolVar = False
31
StrVar = "Hello World"
32
parameterFieldsUsage IntVar, BoolVar, StrVar
33
End Sub
34
35
Public Sub PropertiesUsage()
36
IntVarProp = 0
37
BoolVarProp = False
38
StrVarProp = "Hello World"
39
parameterProperiesUsage IntVarProp, BoolVarProp, StrVarProp
40
End Sub
41
42
Public Sub parameterFieldsUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
43
''
44
End Sub
45
46
Public Sub parameterProperiesUsage(IntVar As Integer, BoolVar As Boolean, StrVar As String)
47
''
48
End Sub
Copied!

C# Code:

1
public int IntVarProp
2
{
3
//some comments for IntVarProp property header
4
get;
5
//some comments for IntVarProp property footer
6
//some comments for IntVarProp property header
7
set;
8
//some comments for IntVarProp property footer
9
}
10
11
public bool BoolVarProp
12
{
13
get;
14
set;
15
}
16
17
public string StrVarProp
18
{
19
get;
20
set;
21
}
22
23
24
public void FieldsUsage()
25
{
26
this.IntVarProp = 0;
27
this.BoolVarProp = false;
28
this.StrVarProp = "Hello World";
29
parameterFieldsUsage(this.IntVarProp, this.BoolVarProp, this.StrVarProp);
30
}
31
32
public void PropertiesUsage()
33
{
34
IntVarProp = 0;
35
BoolVarProp = false;
36
StrVarProp = "Hello World";
37
parameterProperiesUsage(IntVarProp, BoolVarProp, StrVarProp);
38
}
39
40
public void parameterFieldsUsage(int IntVar, bool BoolVar, string StrVar)
41
{
42
//
43
}
44
45
public void parameterProperiesUsage(int IntVar, bool BoolVar, string StrVar)
46
{
47
//
48
}
Copied!

VB.NET Code:

1
Private IntVar As Integer
2
Private BoolVar As Boolean
3
Private StrVar As String = ""
4
5
Public Property IntVarProp() As Integer
6
Get
7
'some comments for IntVarProp property header'
8
Return IntVar
9
'some comments for IntVarProp property footer'
10
End Get
11
Set(ByVal Value As Integer)
12
'some comments for IntVarProp property header'
13
IntVar = Value
14
'some comments for IntVarProp property footer'
15
End Set
16
End Property
17
Public Property BoolVarProp() As Boolean
18
Get
19
Return BoolVar
20
End Get
21
Set(ByVal Value As Boolean)
22
BoolVar = Value
23
End Set
24
End Property
25
Public Property StrVarProp() As String
26
Get
27
Return StrVar
28
End Get
29
Set(ByVal Value As String)
30
StrVar = Value
31
End Set
32
End Property
33
34
Public Sub FieldsUsage()
35
IntVar = 0
36
BoolVar = False
37
StrVar = "Hello World"
38
parameterFieldsUsage(IntVar, BoolVar, StrVar)
39
End Sub
40
41
Public Sub PropertiesUsage()
42
IntVarProp = 0
43
BoolVarProp = False
44
StrVarProp = "Hello World"
45
parameterProperiesUsage(IntVarProp, BoolVarProp, StrVarProp)
46
End Sub
47
48
Public Sub parameterFieldsUsage(ByVal IntVar As Integer, ByVal BoolVar As Boolean, ByVal StrVar As String)
49
''
50
End Sub
51
52
Public Sub parameterProperiesUsage(ByVal IntVar As Integer, ByVal BoolVar As Boolean, ByVal StrVar As String)
53
''
54
End Sub
Copied!

Case Sensitive

.NET Common Language Runtime is case-sensitive. VB.NET code relies on the runtime, which means it must be case-sensitive at runtime, like when it is looking up variables and methods. However, the VB.NET compiler and editor let you ignore that because they correct the case in your code, whereas C# does not, making VB.NET a case-insensitive language (there are exceptions, such as XML literals, and string comparisons).

EWIs

When upgrading a VB6 project to .NET, the Visual Basic Upgrade Companion upgrades most of the code and objects from VB6 to their equivalents in either C# or VB.NET. However, there might be some items that are not fully upgraded, requiring manual changes in order to compile, run and achieve functional equivalence. The Visual Basic Upgrade Companion helps with this process by inserting different Errors, Warnings, and Issues (EWI) information messages into the upgraded code as comments.
EWIs are a valuable part of VB6 to .NET upgrade efforts. They alert you to potential issues, and the upgraded code provides information about how to fix them. An EWI is placed on the line before the problem and it consists of three parts:
Example:
1
//UPGRADE_WARNING: (2080) Form_Load event was upgraded to Form_Load method and has a new behavior. More Information: https://docs.mobilize.net/vbuc/ewis#2080
Copied!
In the example above, an EWI is made up of:
Code Number.
1
(2080)
Copied!
A message describing the problem.
1
Form_Load event was upgraded to Form_Load method and has a new behavior.
Copied!
A link to the help topic.
1
More Information: https://docs.mobilize.net/vbuc/ewis#2080
Copied!
EWIs are inserted into the code as comments, they do not affect the compilation or execution of the upgraded application.
Type
Description