형식 승격(Visual Basic)

모듈에서 프로그래밍 요소를 선언하면 Visual Basic은 해당 범위를 모듈이 포함된 네임스페이스로 승격합니다. 이를 형식 승격이라고 합니다.

다음 예제에서는 모듈의 기본 정의와 해당 모듈의 두 멤버를 보여 줍니다.

Namespace projNamespace
    Module projModule
        Public Enum basicEnum As Integer
            one = 1
            two = 2
        End Enum
        Public Class innerClass
            Shared Sub numberSub(ByVal firstArg As Integer)
            End Sub
        End Class
    End Module
End Namespace

projModule 내에서 모듈 수준에서 선언된 프로그래밍 요소는 projNamespace로 승격됩니다. 이전 예제에서 basicEnuminnerClass는 승격되지만 numberSub은 모듈 수준에서 선언되지 않았기 때문에 승격되지 않습니다.

형식 승격 효과

형식 승격의 효과는 정규화 문자열에 모듈 이름을 포함할 필요가 없다는 것입니다. 다음 예제에서는 이전 예제에서 프로시저를 두 차례 호출합니다.

Sub usePromotion()
    projNamespace.projModule.innerClass.numberSub(projNamespace.projModule.basicEnum.one)
    projNamespace.innerClass.numberSub(projNamespace.basicEnum.two)
End Sub

이전 예제에서 첫 번째 호출은 전체 정규화 문자열을 사용합니다. 그러나 이는 형식 승격으로 인해 반드시 필요하지는 않습니다. 두 번째 호출은 또한 정규화 문자열에 projModule을 포함하지 않고 모듈의 멤버에 액세스합니다.

형식 승격의 무효화

네임스페이스에 모듈 멤버와 같은 이름의 멤버가 이미 있는 경우 해당 모듈 멤버에 대한 형식 승격이 무효화됩니다. 다음 예제에서는 동일한 네임스페이스 내의 열거형 및 모듈의 기본 정의를 보여줍니다.

Namespace thisNamespace
    Public Enum abc
        first = 1
        second
    End Enum
    Module thisModule
        Public Class abc
            Public Sub abcSub()
            End Sub
        End Class
        Public Class xyz
            Public Sub xyzSub()
            End Sub
        End Class
    End Module
End Namespace

앞의 예에서는 네임스페이스 수준에 이미 같은 이름의 열거 형이 있으므로 Visual Basic에서 abc 클래스를 thisNameSpace로 승격할 수 없습니다. abcSub에 액세스하려면 전체 정규화 문자열 thisNamespace.thisModule.abc.abcSub을 사용해야 합니다. 그러나 xyz 클래스는 여전히 승격되며 더 짧은 정규화 문자열 thisNamespace.xyz.xyzSub을 사용하여 xyzSub에 액세스할 수 있습니다.

부분 형식(Partial Type)에 대한 형식 승격의 무효화

모듈 내부의 클래스 또는 구조가 Partial 키워드를 사용하는 경우 네임스페이스에 같은 이름의 멤버가 있는지 여부에 관계없이 해당 클래스 또는 구조에 대해 자동으로 형식 승격이 무효화됩니다. 모듈의 다른 요소는 여전히 형식 승격 대상입니다.

결과. 부분 정의의 형식 승격을 무효화하면 예기치 않은 결과와 컴파일러 오류가 발생할 수 있습니다. 다음 예제에서는 클래스의 기본 부분 정의를 보여 줍니다. 그 중 하나는 모듈 내에 있습니다.

Namespace sampleNamespace
    Partial Public Class sampleClass
        Public Sub sub1()
        End Sub
    End Class
    Module sampleModule
        Partial Public Class sampleClass
            Public Sub sub2()
            End Sub
        End Class
    End Module
End Namespace

이전 예제에서 개발자는 컴파일러가 sampleClass의 두 부분 정의를 병합할 것으로 예상할 수 있습니다. 그러나 컴파일러는 sampleModule 내부의 부분 정의에 대해서는 승격을 고려하지 않습니다. 결과적으로 sampleClass라는 이름이 있지만 서로 다른 자격 경로가 있는 두 개의 별개의 클래스를 컴파일하려고 시도합니다.

컴파일러는 정규화된 경로가 동일한 경우에만 부분 정의를 병합합니다.

권장 사항

다음 권장 사항은 좋은 프로그래밍 방법을 나타냅니다.

  • 고유 이름. 프로그래밍 요소의 이름을 완전히 제어할 수 있는 경우 항상 모든 곳에서 고유한 이름을 사용하는 것이 좋습니다. 동일한 이름은 추가 정규화가 필요하며 코드를 읽기 어렵게 만들 수 있습니다. 또한 미묘한 오류와 예기치 않은 결과를 초래할 수 있습니다.

  • 전체 정규화. 동일한 네임스페이스에서 모듈 및 기타 요소로 작업하는 경우 가장 안전한 방법은 항상 모든 프로그래밍 요소에 대해 전체 정규화를 사용하는 것입니다. 모듈 멤버에 대한 형식 승격이 무효화되고 해당 멤버에 대한 자격을 완전히 갖추지 않은 경우 실수로 다른 프로그래밍 요소에 액세스할 수 있습니다.

참고 항목