Visual Basic 2008의 주요 변경 사항

업데이트: 2008년 7월

다음 표에서는 Visual Studio 2005에서 만든 응용 프로그램이 Visual Studio 2008에서 컴파일되지 않거나 런타임 동작이 달라지게 만들 수 있는 모든 변경 내용을 보여 줍니다.

범주

문제

설명

Nullable 형식

T에서 T?로의 확대 변환은 Visual Studio 2008에 미리 정의된 변환입니다.

Visual Studio 2005에서는 T를 Nullable(Of T)로 확대 변환하기 위한 사용자 정의 변환을 만들 수 있습니다. Visual Studio 2008에서는 nullable 형식에 대한 지원을 확대하는 차원에서 이 변환을 미리 정의하고 있습니다.

오버로드 확인에서는 미리 정의된 변환과 사용자 정의 변환을 모두 고려하므로 이 두 가지 변환이 모두 있는 경우 모호성 문제가 발생할 수 있습니다. 따라서 T에서 T?로의 사용자 정의 확대 변환을 포함하는 코드는 Visual Studio 2008에서 모호할 가능성이 있습니다.

예를 들어 다음 코드에서 c3.Sub1을 호출하면 Visual Studio 2005에서는 문제가 발생하지 않지만 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

사용자 정의 변환을 제거하거나 Class1 또는 Class2로 명시적인 캐스팅을 수행하여 이 문제를 해결할 수 있습니다.

c3.Sub1(CType(sh, Class1))

오버로드 확인

제네릭과 제네릭이 아닌 클래스 간 오버로드 확인의 차이가 수정되었습니다.

Visual Studio 2005에서는 버그로 인해 제네릭 클래스에 대한 오버로드 확인 동작이 제네릭이 아닌 클래스에 대한 오버로드 확인 동작과 다른 경우가 있습니다. 다음 예제에서 Class1과 Class2는 Class2에 제네릭 매개 변수가 정의되어 있다는 점을 제외하고는 동일합니다. Main의 c1.Sub1에 대한 호출은 전달된 인수가 Class1의 어느 Sub1 오버로드로도 바인딩될 수 있으므로 모호합니다. 이 모호성으로 인해 Visual Studio 2005 및 Visual Studio 2008 모두에서 컴파일러 오류가 발생합니다.

c2.Sub1에 대한 호출에서도 동일한 오류가 발생해야 하지만 Visual Studio 2005에서는 오류가 발생하지 않습니다. 대신 이 메서드는 Class2의 제약 조건이 없는 Sub1 오버로드로 바인딩됩니다. .

이 문제는 Visual Studio 2008에서 수정되었습니다. 즉 두 호출 모두에서 모호성으로 인한 컴파일러 오류가 발생합니다. 다음 코드에서는 이 과정을 보여 줍니다.

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

모호하지 않도록 오버로드를 변경하거나 형식 인수를 명시적으로 지정하여 이 문제를 해결할 수 있습니다.

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

오버로드 확인

Visual Studio 2008에서는 제네릭과 ParamArray 매개 변수의 오버로드 확인에서 서로 다른 결과가 발생합니다.

오버로드 확인의 목표는 메서드에 전달된 인수의 형식과 가장 일치하는 매개 변수를 가진 후보 메서드를 선택하는 것입니다. 이 단원의 예제에서 Sub1은 상속 계층 구조 전체에서 오버로드되며 Integer 및 Short 형식의 인수를 사용하여 호출됩니다.

Visual Studio 2005 및 Visual Studio 2008의 오버로드 확인 규칙에서는 모두 직접 일치가 ParamArray 매개 변수가 필요한 일치보다 더 적합한 일치라고 지정하고 있습니다. 하지만 Visual Studio 2005 오버로드 확인 규칙을 사용하면 파생 클래스인 Class2에서 오버로드 후보에 대한 형식 유추가 실패합니다. 그 이유는 Y가 동시에 Integer 및 Short가 될 수 없고 정확한 일치가 필요하기 때문입니다. 인수 sh와 n의 형식이 같다면 Class2의 Sub1이 ParamArray 매개 변수가 있는 Class1의 후보보다 선호될 것입니다. 하지만 두 인수의 형식이 다르므로 Class1의 기본 클래스 오버로드가 대신 선택됩니다. T는 Integer로 유추되고 Short는 ParamArrayp로 확대 변환됩니다.

이 경우를 제외하면 Visual Studio 2008은 Visual Studio 2005와 동일한 오버로드를 선택하는 새 알고리즘을 사용합니다. Visual Studio 2008에서는 이 알고리즘에 따라 이 예제에서 Integer가 기준 형식이 되는데 그 이유는 Short가 Integer로 확대 변환되기 때문입니다. 파생 클래스의 형식 매개 변수 Y는 Integer로 유추되고 Short는 Integer로 확대 변환됩니다. 따라서 파생 클래스의 Sub1이 호출됩니다.

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

Sub1을 호출하기 전에 변수 c2를 C1ass1 형식으로 캐스팅하거나 인수 sh를 배열로 전달하여 Visual Studio 2005의 동작을 지정할 수 있습니다.

' 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})

참고 항목

개념

오버로드 확인

Nullable 값 형식

Visual Basic의 제네릭 형식

참조

ParamArray

변경 기록

날짜

변경 내용

이유

2008년 7월

항목이 추가되었습니다.

향상된 기능 관련 정보