Export (0) Print
Expand All

Visual Basic 2008 Breaking Changes

Updated: July 2008

The following table lists all the changes that might prevent an application that was created in Visual Studio 2005 from compiling in Visual Studio 2008, or that might change its run-time behavior.

Category

Issue

Description

Nullable types

T widening to T? is a predefined conversion in Visual Studio 2008.

In Visual Studio 2005, you can create a user-defined conversion to enable T to widen to Nullable(Of T). As part of the increased support for nullable types in Visual Studio 2008, this conversion is predefined.

Because overload resolution considers both predefined and user-defined conversions, there is a potential ambiguity if both exist. Therefore, code that contains a user-defined widening conversion from T to T? is potentially ambiguous in Visual Studio 2008.

For example, in the following code, the call to c3.Sub1 works in Visual Studio 2005 but causes a compiler error in Visual Studio 2008.

Module Module1

    Sub Main()
        Dim c3 As New Class3
        Dim sh As Short = 2
        ' The following statement compiles in Visual Studio 2005, 
        ' but causes an error in Visual Studio 2008. 
        'c3.Sub1(sh) 
    End Sub 

End Module 

Class Class1
    Public Shared Widening Operator CType(ByVal s As  _
                                          Nullable(Of Short)) As Class1
        Return New Class1()
    End Operator 
End Class 

Class Class2
    Public Shared Widening Operator CType(ByVal n As Integer) As Class2
        Return New Class2()
    End Operator 
End Class 

Class Class3
    Sub Sub1(ByVal c As Class1)
    End Sub 

    Sub Sub1(ByVal c As Class2)
    End Sub 
End Class

To resolve this issue, you can remove the user-defined conversion, or you can explicitly cast to Class1 or Class2:

c3.Sub1(CType(sh, Class1))

Overload resolution

Overload resolution differences between generic and non-generic classes have been corrected.

A bug in Visual Studio 2005 can cause overload resolution behavior for generic classes to be different from that of non-generic classes. In the following example, Class1 and Class2 are identical except that Class2 has a generic parameter defined on it. The call to c1.Sub1 in Main is ambiguous because the argument passed in could bind to either overload of Sub1 in Class1. The ambiguity causes a compiler error in both Visual Studio 2005 and Visual Studio 2008.

The call to c2.Sub1 should generate the same error, but in Visual Studio 2005 it does not. Instead, the method binds to the unconstrained overload of Sub1 in Class2.

This issue is fixed in Visual Studio 2008. Both calls generate compiler errors because of the ambiguity. This is illustrated in the following code:

Module Module1

    Sub Main()
        Dim c1 As New Class1
        Dim c2 As New Class2(Of String)
        ' The following statement causes a compiler error in both  
        ' Visual Studio 2005 and Visual Studio 2008. 
        'c1.Sub1(New Nullable(Of Integer)) 

        ' The following statement causes a compiler error only 
        ' in Visual Studio 2008. 
        'c2.Sub1(New Nullable(Of Integer)) 
    End Sub 

End Module 

Class Class1
    Sub Sub1(Of T)(ByVal arg As T)
        Console.WriteLine("Unconstrained Sub1 in Class1")
    End Sub 

    Sub Sub1(Of T As Structure)(ByVal arg As Nullable(Of T))
        Console.WriteLine("Constrained Sub1 in Class1")
    End Sub 
End Class 

Class Class2(Of U)
    Sub Sub1(Of T)(ByVal arg As T)
        Console.WriteLine("Unconstrained Sub1 in Class2")
    End Sub 

    Sub Sub1(Of T As Structure)(ByVal arg As Nullable(Of T))
        Console.WriteLine("Constrained Sub1 in Class2")
    End Sub 
End Class

To resolve this issue, you can change the overloads so that they are no longer ambiguous, or you can specify the type arguments explicitly:

c1.Sub1(Of Integer?)(New Nullable(Of Integer))
c2.Sub1(Of Integer?)(New Nullable(Of Integer))

Overload resolution

Overload resolution with generic and ParamArray parameters produces different results in Visual Studio 2008.

The goal of overload resolution is to try to select the candidate method whose parameters most closely match the types of the arguments that are passed to the method. In the example in this section, Sub1 is overloaded across an inheritance hierarchy, and is called with arguments of type Integer and Short.

Overload resolution rules in both Visual Studio 2005 and Visual Studio 2008 specify that direct matches are better matches than those requiring ParamArray parameters. However, using Visual Studio 2005 overload resolution rules, type inference fails for the overload candidate in the derived class, Class2, because Y cannot be both an Integer and a Short, and exact matches are required. If arguments sh and n were of the same type, the Sub1 in Class2 would be preferred over the candidate in Class1, which has a ParamArray parameter. However, because the two arguments have different types, the base class overload in Class1 is selected instead. T is inferred as Integer, and Short widens into the ParamArray p.

Visual Studio 2008 uses a new algorithm that selects the same overloads as Visual Studio 2005, except in this specific case. In Visual Studio 2008, the algorithm determines that Integer is the dominant type in this example, because Short widens to Integer. Type parameter Y in the derived class is inferred to be Integer, and Short widens to Integer. As a result, the Sub1 in the derived class is called.

Module Module1

    Sub Main()
        Dim c2 As New Class2
        Dim n As Integer 
        Dim sh As Short
        c2.Sub1(n, sh)
    End Sub 

    Class Class1
        Sub Sub1(Of T)(ByVal arg1 As T, ByVal ParamArray p() As Integer)
            Console.WriteLine("Visual Studio 2005 calls Sub1 " & _
                              "in the *base* class.")
        End Sub 
    End Class 

    Class Class2 : Inherits Class1
        Overloads Sub Sub1(Of Y)(ByVal arg1 As Y, ByVal arg2 As Y)
            Console.WriteLine("Visual Studio 2008 calls Sub1 " & _
                              "in the *derived* class.")
        End Sub 
    End Class 

End Module

You can force Visual Studio 2005 behavior by casting variable c2 to type C1ass1 before you call Sub1, or by passing argument sh as an array.

' You can cast variable c2 to Class1 in order to force Visual
' Studio 2005 behavior.
CType(c2, Class1).Sub1(n, sh)
' Alternatively, you can pass sh as an array.
c2.Sub1(n, New Integer() {sh})

Date

History

Reason

July 2008

Added topic.

Information enhancement.

Community Additions

ADD
Show:
© 2014 Microsoft