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.
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:
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:
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.