Поделиться через


Повышение типов (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. В приведенном выше примере basicEnum и innerClass продвигаются, но 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 не может повысить уровень класса abcthisNameSpace , так как уже существует перечисление с тем же именем на уровне пространства имен. Чтобы получить доступ к abcSub, необходимо использовать полную строку квалификации thisNamespace.thisModule.abc.abcSub. Однако класс xyz всё ещё считается продвигаемым, и вы можете получить доступ к элементу xyzSub под более короткой строкой квалификации thisNamespace.xyz.xyzSub.

Недостатки типизации для частичных типов

Если класс или структура внутри модуля использует ключевое слово 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 , так и с различными путями квалификации.

Компилятор объединяет частичные определения только в том случае, если их полные пути идентичны.

Рекомендации

Следующие рекомендации представляют собой хорошую практику программирования.

  • Уникальные имена. Если у вас есть полный контроль над именованием элементов программирования, всегда рекомендуется использовать уникальные имена везде. Идентичные имена требуют дополнительной квалификации и могут усложнять чтение кода. Они также могут привести к тонким ошибкам и непредвиденным результатам.

  • Полная квалификация. При работе с модулями и другими элементами в одном пространстве имен самый безопасный подход — всегда использовать полную квалификацию для всех элементов программирования. Если не удается совершить преобразование типа для члена модуля и вы не полностью квалифицируете этот член, вы можете случайно получить доступ к другому программному элементу.

См. также