名前空間とは、プロシージャや変数をまとめておくモジュールクラス自体をまとめるための論理的な構造です。 すべてのモジュール・クラス(といくつかの要素)は必ず何らかの名前空間に属しています。 その一方、変数やプロシージャなどは必ずモジュールまたはクラスに属しているので、単独で名前空間に直接属することはありません。

名前空間は、モジュール・クラスをただ単にまとめるだけでなく、それらをグループ化することで識別子(名前)が重複するのを防ぐために使われます。 たとえば、.NET FrameworkのSystem名前空間にはInt32、Singleなどの基本型の構造体や、String、Array、Console、Mathなどのクラスが宣言されていますし、System.Windows.Forms名前空間にはフォームのコントロールとなるクラスが多数宣言されています。 独自に作成したクラスにStringやControlという名前を付けることも出来ますが、そういったクラスが個別の名前空間に格納されていれば、.NET Frameworkに存在する同名のクラスと区別することが可能になります。

§1 完全修飾名

モジュール・クラスをはじめ、すべての型は完全修飾名を持っています。 これはモジュール・クラスそれ自体の名前に加え、そのモジュール・クラスが宣言されている名前空間を連結した名前です。 すべての型はこの完全修飾名によって識別されます。

例えば、System名前空間にあるMathクラスはSystem.Math、System.Text名前空間にあるEncodingクラスはSystem.Text.Encodingがその完全修飾名となります。



§2 既定の名前空間

すべてのモジュール・クラスは何らかの名前空間に属するとされていますが、このコードを見る限りは名前空間に関するキーワードは出てきません。

Module MainModule

    Sub Main()

        Console.WriteLine("Hello, world!")

    End Sub

End Module

というのも、VB.NETではプロジェクトに既定の名前空間を指定できるためで、既定の名前空間が指定されている場合はこれらのモジュール・クラスはその名前空間に属することになります。

プロジェクトのプロパティ

「プロジェクトのプロパティ」ダイアログを開くと、「ルート名前空間」という項目がありますが、ここに記述されている名前が既定の名前空間になります。

§3 名前空間の宣言

特に名前空間を指定しない限りは、モジュールやクラスは既定の名前空間に属します。 指定した名前空間に属するようにする場合はNamespaceキーワードを使用します。

Namespace SampleNamespace

    Module MainModule

        Sub Main()

            Console.WriteLine("Hello, world!")

        End Sub

    End Module

End Namespace

この例のように名前空間の宣言はNamespace〜End Namespaceで行い、その間の部分でモジュール・クラスを宣言します。

この例において、既定の名前空間が MyProject の場合、宣言した名前空間は MyProject 名前空間に属する MyProject.SampleNamespace 名前空間になります。 また、MainModuleは MyProject.SamleNamespace 名前空間に属することになり、その完全修飾名は MyProject.SampleNamespace.MainModule となります。

§4 他の名前空間からの参照

他の名前空間から別の名前空間にあるモジュールのプロシージャを参照する場合は次のようにします。

Namespace AnotherNamespace

    Module AnotherModule

        Sub ShowMessage()

            Console.WriteLine("Hello, world")

        End Sub

    End Module

End Namespace

Namespace MainNamespace

    Module MainModule

        Sub Main()

            AnotherNamespace.AnotherModule.ShowMessage()

        End Sub

    End Module

End Namespace

他の名前空間のモジュール内にあるメンバを参照するには 名前空間.モジュール名.メンバ名 とします。 ただし、この例のようにモジュールで宣言されているメンバは、名前空間から記述する場合はモジュール名を省略して参照することも出来るため、単に 名前空間.プロシージャ名 とする事もできます。

Sub Main()

    ' ShowMessage()はモジュールのメンバなのでモジュール名を省略できる
    AnotherNamespace.ShowMessage()

End Sub

§5 複数箇所での名前空間の宣言

同名の名前空間を複数に分割して宣言することもできます。 その場合、そこで宣言されているモジュール・クラスは同じ名前空間に属しているので当然互いに参照することができます。

Namespace MainNamespace

    ' 名前空間MainNamespaceのモジュールMainModule
    Module MainModule

        Sub Main()

            ' 同一名前空間にあるのでモジュール名は省略できる
            ShowMessage()

        End Sub

    End Module

End Namespace


' 同じMainNamespace名前空間であることに注目してください
Namespace MainNamespace

    ' 名前空間MainNamespaceのモジュールAnotherModule
    Module AnotherModule

        Sub ShowMessage()

            Console.WriteLine("Hello, world")

        End Sub

    End Module

End Namespace

このコードは次のコードと全く等価です。

Namespace MainNamespace

    ' 名前空間MainNamespaceのモジュールMainModule
    Module MainModule

        Sub Main()

            ' 同一名前空間にあるのでモジュール名を省略できる
            ShowMessage()

        End Sub

    End Module

    ' 名前空間MainNamespaceのモジュールAnotherModule
    Module AnotherModule

        Sub ShowMessage()

            Console.WriteLine("Hello, world")

        End Sub

    End Module

End Namespace

§6 入れ子構造になった名前空間

次のコードのように名前空間の中に名前空間を宣言することもできます。

Namespace MainNamespace

    Namespace SubNamespace

        :
        :

    End Namespace

End Namespace

これは次のようにも表現できます。

Namespace MainNamespace.SubNamespace

    :
    :

End Namespace

プロジェクトに既定の名前空間が指定されていれば、宣言した名前空間はすべて既定の名前空間の中に宣言されたものとして扱われます。

§7 名前空間の省略(Importsキーワード)

深い入れ子関係の名前空間を参照する場合次のように非常にコードが煩雑になります。

Module MainModule

    Sub Main()

        ' このクラスは.NET Frameworkに実際に存在する
        ' フォームの雛型となるクラスです
        Dim frm As System.Windows.Forms.Form

    End Sub

End Module

このような長い名前空間名を毎回記述するのは非常に面倒なので、これを省略するためにImportsキーワードが用意されています。

' System.Windows.Forms名前空間をインポートします
Imports System.Windows.Forms

Module MainModule

    Sub Main()

        Dim frm As Form

        'このコードは次のコードと等価です
        'Dim frm As System.Windows.Forms.Form

    End Sub

End Module

ただし、名前空間をインポートすることで名前の衝突が発生するおそれがあります。 たとえば、次のように二つの名前空間にそれぞれSampleClassというクラスが存在しているとします。

Namespace SampleNamespace1

    Class SampleClass
    End Class

End Namespace


Namespace SampleNamespace2

    Class SampleClass
    End Class

End Namespace

そして、この名前空間をインポートしてSampleClassを参照しようとします。

' プロジェクトの既定の名前空間から記述する必要があります
Imports SampleConsoleApplication.SampleNamespace1
Imports SampleConsoleApplication.SampleNamespace2

Module SampleModule

    Sub Main()

        Dim s As SampleClass

    End Sub

End Module

そうすると、このSampleClassはSampleNamespace1のものかSampleNamespace2のものか区別する手段がないので、このコードはコンパイルエラーになります。 こうなると名前の重複を防ぐ目的である名前空間の存在意義がなくなってしまうので、名前空間をインポートした場合でも次のように限密名を指定することで重複を防ぐことができます。

' プロジェクトの既定の名前空間から記述する必要があります
Imports SampleConsoleApplication.SampleNamespace1
Imports SampleConsoleApplication.SampleNamespace2

Module SampleModule

    Sub Main()

        ' SampleNamespace1名前空間のSampleClassを参照します
        Dim s1 As SampleNamespace1.SampleClass

        ' SampleNamespace1名前空間のSampleClassを参照します
        Dim s2 As SampleNamespace1.SampleClass

    End Sub

End Module

§8 名前空間のエイリアス

名前空間をインポートする際に別名(エイリアス)をつけることができます。 これによって長い名前空間の名前を短くして使用することができます。

' System.Windows.Forms 名前空間を WinForms という名前でインポートします
Imports WinForms = System.Windows.Forms

Module SampleModule

    Sub Main()

        ' これら二つの宣言は等価です
        Dim frm1 As WinForms.Form

        Dim frm2 As System.Windows.Forms.Form

    End Sub

End Module