VB Migration Partner is capable, in most cases, to correctly deduce a less generic data type for Variant local variables, parameters, class fields, functions and properties. This applies both to members that were explicitly declared as Variant and to members that lacked an explicit As clause. To see how this feature works, consider the following VB6 code:

'## DeclareImplicitVariables True

Private m_Width As Single

Property Get Width ()
    Width = m_Width
End Property

Property Let Width (value)
    m_Width = value
End Property

Sub Test(x As Integer, frm)
    Dim v1 As Variant, v2
    v1 = x * 10
    v2 = Width + x
    Set frm = New frmMain
    res = frm.Caption
End Sub

By default this code is converted to VB.NET as follows:

Private m_Width As Single

Public Property Width() As Object
    Get
        ' UPGRADE_WARNING (#0364): Unable to assign default member of 'Width'.
        ' Consider using the SetDefaultMember6 helper method.

        Return m_Width
     End Get
    Set(ByVal value As Object)
        ' UPGRADE_WARNING (#0354): Unable to read default member of 'value'.
        ' Consider using the GetDefaultMember6 helper method.

        m_Width = value
     End Set
End Property

Public Sub Test(ByRef x As Short, ByRef frm As Object)
    ' UPGRADE_INFO (#05B1): The 'res' variable wasn't declared explicitly.
    Dim res As Object = Nothing
    ' UPGRADE_INFO (#0561): The 'frm' symbol was defined without an
    ' explicit "As" clause.

    Dim v1 As Object = Nothing
    ' UPGRADE_INFO (#0561): The 'v2' symbol was defined without an
    ' explicit "As" clause.

    Dim v2 As Object = Nothing
    ' UPGRADE_WARNING (#0364): Unable to assign default member of 'v1'.
    ' Consider using the SetDefaultMember6 helper method.
    v1 = x * 10
    ' UPGRADE_WARNING (#0364): Unable to assign default member of 'v2'.
    ' Consider using the SetDefaultMember6 helper method.

    v2 = Width + x
    frm = New Form1()
    ' UPGRADE_WARNING (#0354): Unable to read default member of
    ' 'frm.Caption'. Consider using the GetDefaultMember6 helper method.
    ' UPGRADE_WARNING (#0364): Unable to assign default member of 'res'.
    ' Consider using the SetDefaultMember6 helper method.

    res = frm.Caption
End Sub

Variant variables – either implicitly declared or not – are translated into Object variables, which causes several warning to be emitted and, more important, adds an overhead at runtime. This overhead can be often avoided by declaring the variable of a more defined scalar type. You can have VB Migration Partner change the data type for a given member by means of the SetType pragma, but this operation requires a careful analysis of which values are assigned to the variable.

Users of VB Migration Partner 1.10 can have this analysis performed automatically, by inserting an InferType pragma at the project-, file-, method- or variable-level. For example, let’s assume that the previous VB6 code contains the following pragma at the file level:

'## InferType Yes

The Yes argument in this pragma makes VB Migration Partner attempt to infer the type of al the implicitly-declared local variables and of all the local variables, class fields, functions and properties that lack an explicit As clause:

Private m_Width As Single

Public Property Width() As Single
    Get
        Return m_Width
    End Get
    Set(ByVal value As Single)
        m_Width = value
    End Set
End Property

Public Sub Test(ByRef x As Short, ByRef frm As Object)
    ' UPGRADE_INFO (#0561): The 'frm' symbol was defined without an
    ' explicit "As" clause.
    ' UPGRADE_INFO (#05B1): The 'res' variable wasn't declared explicitly.

    Dim res As Object = Nothing
    Dim v1 As Object = Nothing
    ' UPGRADE_INFO (#0561): The 'v2' symbol was defined without an
    ' explicit "As" clause.

    Dim v2 As Single
    ' UPGRADE_WARNING (#0364): Unable to assign default member of 'v1'.
    ' Consider using the SetDefaultMember6 helper method.

    v1 = x * 10
    v2 = Height + x
    frm = New Form1()
    ' UPGRADE_WARNING (#0354): Unable to read default member of
    ' 'frm.Caption'. Consider using the GetDefaultMember6 helper method.
    ' UPGRADE_WARNING (#0364): Unable to assign default member of 'res'.
    ' Consider using the SetDefaultMember6 helper method.

    res = frm.Caption
End Sub

In this new version, VB Migration Partner can infer the type of the Width property from the type of the m_Width variable, which in turn permits to infer the type of the v2 local variable. VB Migration Partner attempts to infer neither the type of the v1 local variable (because it is explicitly declared As Variant) nor the type of the frm parameter (because by default method parameters aren’t under the scope of the InferType pragma).

You can extend type inference to members that were declared with an explicit As Variant by using the Force argument in the pragma. In addition, passing True in the second (optional) argument extends the scope to method parameters:

'## InferType Force, True

The result of the conversion is now the following:

Private m_Width As Single

Public Property Width() As Single
    Get
        Return m_Width
    End Get
    Set(ByVal value As Single)
        m_Width = value
    End Set
End Property

Public Sub Test(ByRef x As Short, ByRef frm As Form1)
    ' UPGRADE_INFO (#0561): The 'frm' symbol was defined without an
    ' explicit "As" clause.
    ' UPGRADE_INFO (#05B1): The 'res' variable wasn't declared explicitly.

    Dim res As String = Nothing
    Dim v1 As Integer
    ' UPGRADE_INFO (#0561): The 'v2' symbol was defined without an
    ' explicit "As" clause.

    Dim v2 As Single
    v1 = x * 10
    v2 = Width + x
    frm = New Form1()
    res = frm.Caption
End Sub

Notice that in this new version the type of frm parameter is inferred correctly, which in turn permits to infer the type of the res local variable.

Type inference works both with scalar types and object types. Deducing the correct type of an object often produces faster and more readable code. For example, consider the following VB6 code:

'## InferType
Public Sub SetAddress(ByVal address As String)
    Dim tb
    Set tb = Me.txtAddress  ' (txtAddress is a TextBox)
    tb = address
End Sub

VB Migration Partner can infer that the tb variable is of type TextBox and, consequently, it can correctly expand its default property:

Public Sub SetAddress(ByVal address As String)
    Dim tb As VB6TextBox = Me.txtAddress    
    tb.Text = address
End Sub


Extending the pragma scope to method parameters isn’t always a good idea, because the current version of VB Migration Partner infers the type of parameters by looking at assignments inside the method and doesn’t account for implicit assignments that result from method calls. For this reason, the type inferred during the migration process might not be correct in some cases.

Important note: Type inference isn’t an exact science and you should always double-check that the data type inferred by VB Migration Partner is correct. Better, we recommend that you use the InferType pragma only during early migration attempts and then you later assign a specific type to members by editing the original VB6 code or by means of the SetType pragma.