次の方法で共有


型の昇格 (Visual Basic)

モジュールでプログラミング要素を宣言すると、Visual Basic は、そのスコープをモジュールを含む名前空間に昇格します。 これは 型の昇格と呼ばれます。

次の例は、モジュールのスケルトン定義とそのモジュールの 2 つのメンバーを示しています。

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 は昇格されません。

型昇格の効果

型の昇格の効果は、修飾文字列にモジュール名を含める必要がないようにすることです。 次の例では、前の例のプロシージャを 2 回呼び出します。

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

前の例では、最初の呼び出しでは完全な修飾文字列が使用されています。 ただし、これは型の昇格のために必要ありません。 2 番目の呼び出しでは、修飾文字列に 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はまだ昇格されており、短い修飾文字列thisNamespace.xyz.xyzSubを使用してxyzSubにアクセスできます。

部分型の型昇格の無効化

モジュール内のクラスまたは構造体が Partial キーワードを使用している場合、名前空間に同じ名前のメンバーがあるかどうかに関係なく、そのクラスまたは構造体に対して型の昇格は自動的に無効になります。 モジュール内の他の要素は、引き続き型の昇格の対象となります。

結果。 部分定義の型昇格が行われなくても、予期しない結果やコンパイラ エラーが発生する可能性があります。 次の例は、クラスのスケルトン部分定義を示しています。そのうちの 1 つはモジュール内にあります。

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 の 2 つの部分的な定義をマージすることを想定している場合があります。 ただし、コンパイラでは、 sampleModule内の部分定義の昇格は考慮されません。 その結果、 sampleClass という名前の異なる修飾パスを持つ 2 つの個別のクラスをコンパイルしようとします。

コンパイラは、完全修飾パスが同一の場合にのみ、部分定義をマージします。

推奨事項

次の推奨事項は、適切なプログラミングプラクティスを表しています。

  • 一意の名前。 プログラミング要素の名前付けを完全に制御できる場合は、常に一意の名前をどこでも使用することをお勧めします。 同じ名前には追加の修飾が必要であり、コードの読み取りが困難になる可能性があります。 また、微妙なエラーや予期しない結果につながる可能性もあります。

  • 完全な資格。 同じ名前空間内のモジュールやその他の要素を操作する場合、最も安全な方法は、すべてのプログラミング要素に対して常に完全な修飾を使用することです。 モジュール メンバーの型昇格が無効になり、そのメンバーを完全に修飾しないと、誤って別のプログラミング要素にアクセスする可能性があります。

こちらも参照ください