Promoção de tipos (Visual Basic)
Quando você declara um elemento de programação em um módulo, o Visual Basic promove o escopo dele para o namespace que contém o módulo. Isso é conhecido como promoção de tipo.
O exemplo a seguir mostra uma definição de esqueleto de um módulo e dois membros desse módulo.
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
Dentro do projModule
, os elementos de programação declarados no nível do módulo são promovidos a projNamespace
. No exemplo anterior, basicEnum
e innerClass
são promovidos, mas numberSub
não é, porque não é declarado no nível do módulo.
Efeito da Promoção de Tipos
O efeito da promoção de tipos é que uma cadeia de caracteres de qualificação não precisa incluir o nome do módulo. O exemplo a seguir faz duas chamadas para o procedimento no exemplo anterior.
Sub usePromotion()
projNamespace.projModule.innerClass.numberSub(projNamespace.projModule.basicEnum.one)
projNamespace.innerClass.numberSub(projNamespace.basicEnum.two)
End Sub
No exemplo anterior, a primeira chamada usa cadeias de caracteres de qualificação completas. No entanto, isso não é necessário devido à promoção de tipos. A segunda chamada também acessa os membros do módulo sem incluir projModule
nas cadeias de caracteres de qualificação.
Derrota da Promoção de Tipos
Se o namespace já tiver um membro com o mesmo nome que um membro do módulo, a promoção de tipos será derrotada para esse membro do módulo. O exemplo a seguir mostra uma definição de esqueleto de uma enumeração e um módulo dentro do mesmo namespace.
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
No exemplo anterior, o Visual Basic não pode promover a classe abc
a thisNameSpace
porque já há uma enumeração com o mesmo nome no nível do namespace. Para acessar abcSub
, você precisa usar a cadeia de caracteres de qualificação thisNamespace.thisModule.abc.abcSub
completa. No entanto, a classe xyz
ainda é promovida e você pode acessar xyzSub
com a cadeia de caracteres de qualificação thisNamespace.xyz.xyzSub
mais curta.
Derrota da Promoção de Tipos para Tipos Parciais
Se uma classe ou estrutura dentro de um módulo usar a palavra-chave Parcial, a promoção de tipos será derrotada automaticamente para essa classe ou estrutura, independentemente de o namespace ter ou não um membro com o mesmo nome. Outros elementos no módulo ainda são qualificados para promoção de tipos.
Consequências. A derrota da promoção de tipos de uma definição parcial pode causar resultados inesperados e até erros do compilador. O exemplo a seguir mostra definições parciais de esqueleto de uma classe, uma das quais está dentro de um módulo.
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
No exemplo anterior, o desenvolvedor pode esperar que o compilador mescle as duas definições parciais de sampleClass
. No entanto, o compilador não considera a promoção para a definição parcial dentro de sampleModule
. Como resultado, ele tenta compilar duas classes separadas e distintas, ambas nomeadas sampleClass
, mas com caminhos de qualificação diferentes.
O compilador mescla definições parciais somente quando seus caminhos totalmente qualificados são idênticos.
Recomendações
As recomendações a seguir representam uma boa prática de programação.
Nomes Exclusivos. Quando você tem controle total sobre a nomenclatura de elementos de programação, é sempre uma boa ideia usar nomes exclusivos em todos os lugares. Nomes idênticos exigem qualificação extra e podem dificultar a leitura do código. Eles também podem levar a erros sutis e resultados inesperados.
Qualificação Completa. Quando você está trabalhando com módulos e outros elementos no mesmo namespace, a abordagem mais segura é sempre usar a qualificação completa para todos os elementos de programação. Se a promoção de tipos for derrotada para um membro do módulo e você não qualificar totalmente esse membro, você poderá acessar inadvertidamente um elemento de programação diferente.