Previous | Index | Next 

[HOWTO] Using the SetType pragma with optional parameters

Note: this article only applies to conversions to VB.NET.

VB Migration Partner allows you to use the SetType pragma to change the type of all kinds of members. However, please be aware that VB Migration Partner can’t automatically fix all sorts of problems that can derive by the type change.

One of such problems are apparent when you use the SetType pragma to set the type of an optional Variant parameter to something else. For example, consider this code:

        Sub Test(Optional name As Variant, Optional value As Variant)
            '## name.SetType String
            If IsMissing(name) Then
                ' process a missing name
            End If
            If IsMissing(value) Then
                ' process a missing value
            End If
            ...
        End Sub

The above VB6 code is translated to VB.NET as follows:

        Sub Test(Optional ByRef name As String = MissingValue6, _
                   Optional ByRef value As Object = MissingValue6)
            FixOptionalParameter6(value)
            If IsMissing6(name) Then
                ' process a missing name
            End If
            If IsMissing6(value) Then 
                ' process a missing value
            End If
            ...
        End Sub

Notice that VB Migration Partner doesn’t include the name parameter in the call to FixOptionalParameter6 helper method, because non-Object values would cause an exception if passed to that method.

The above code runs exactly as in VB6, because the IsMissing6 function returns True both if the argument is a string equal to MissingValue6 and if the argument is a value equal to System.Reflection.Missing.Value.

However, now consider what happens if you add a SetType pragma to change the type of the value parameter:

        Sub Test(Optional name As Variant, Optional value As Variant)
            '## name.SetType String
            '## value.SetType Double
            ' (remainder of code as before...)
        End Sub

This is the code that VB Migration Partner emits in this case:

        Sub Test(Optional ByRef name As String = MissingValue6, _
                   Optional ByRef value As Double = MissingValue6)
            FixOptionalParameter6(value)
            If IsMissing6(name) Then
                ' process a missing name
            End If
            If IsMissing6(value) Then 
                ' process a missing value
            End If
            ...
        End Sub

This code has two problems. First, assigning the MissingValue6 string constant to a Double parameter causes a compile error. Second, even if you adjust the default value for the second parameter, the IsMissing6 function returns False when passed a Double value.

The easiest way to solve the first problem is by means of PostProcess pragma. For example, the following pragma replaces MissingValue6 with NegativeInfinity when used as the default value of a Double argument:

        '## PostProcess "(?<=\bOptional\s+(ByVal|ByRef)\s+\w+\s+As\s+
             Double\s*=\s*)MissingValue6\b", Double.NegativeInfinity, True

The only way to solve the second problem is to use a ReplaceStatement pragma to replace the IsMissing statement, for example:

        '## ReplaceStatement If Double.IsNegativeInfinity(value) Then
        If IsMissing(value) Then
             ' process a missing value
         End If

The entire VB6 code therefore becomes:

        '## PostProcess "(?<=\bOptional\s+(ByVal|ByRef)\s+\w+\s+As\s+
             Double\s*=\s*)MissingValue6\b", Double.NegativeInfinity, True

        Sub Test(Optional name As Variant, Optional value As Variant)
            '## name.SetType String
            '## value.SetType Double
            If IsMissing(name) Then
                ' process a missing name
            End If
            '## ReplaceStatement If Double.IsNegativeInfinity(value) Then
            If IsMissing(value) Then 
                ' process a missing value
            End If
            ...
        End Sub

 

Previous | Index | Next