名前空間

注意:
この文書は以前「.NETでいきまっしょい!」で公開していたものですが、公開以降メンテナンスされていません。 今や古い情報となった内容が記載されている場合があるのでご注意ください。

名前空間とは

 名前空間とは、プロシージャや変数をまとめておくモジュールやクラス自体をまとめるための構造です。 すべてのモジュール・クラス(といくつかの要素)は必ず何らかの名前空間に属しています。 その一方、変数やプロシージャなどが単独で名前空間に直接属することはありません。
 名前空間は、モジュール・クラスをただ単にまとめるだけでなく、それらをグループ化することで識別子(名前)が重複するのを防ぐために使われます。 たとえば、.NET FrameworkのSystem名前空間にはInt32、Singleなどの基本型の構造体や、String、Array、Console、Mathなどのクラスが宣言されていますし、System.Windows.Forms名前空間にはフォームのコントロールとなるクラスが多数宣言されています。

既定の名前空間

 すべてのモジュール・クラスは何らかの名前空間に属するとしましたが、このコードを見る限りは名前空間に関するキーワードは出てきません。
001
002
003
004
005
006
007
008
009
Module MainModule

    Sub Main()

        Console.WriteLine("Hello, world!")

    End Sub

End Module
 というのも、VB.NETではプロジェクトに既定の名前空間を指定できるためで、既定の名前空間が指定されている場合はこれらのモジュール・クラスはその名前空間に属することになります。
プロジェクトのプロパティ
 「プロジェクトのプロパティ」ダイアログを開くと、「ルート名前空間」という項目がありますが、ここに記述されている名前が既定の名前空間になります。

名前空間の宣言

 特に名前空間を指定しない限りは、モジュール・クラスは既定の名前空間に属します。 他の名前空間に属するようにする場合はNamespaceキーワードを使用します。
001
002
003
004
005
006
007
008
009
010
011
012
013
Namespace SampleNamespace

    Module MainModule

        Sub Main()

            Console.WriteLine("Hello, world!")

        End Sub

    End Module

End Namespace
 既定の名前空間が「SampleProject」の場合、MainModuleは「SampleProject.SamleNamespace」に属することになります。 この例のように名前空間の宣言はNamespace〜End Namespaceで行い、その間にモジュール・クラスを宣言します。

他の名前空間からの参照

 他の名前空間から別の名前空間にあるモジュールのプロシージャを参照する場合は次のようにします。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
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
 他の名前空間のモジュール内にあるプロシージャを参照するには「名前空間.モジュール名.プロシージャ名」とします。 ただしこの場合、ShowMessage()プロシージャのスコープはPublicなので、モジュール名を省略することができ「名前空間.プロシージャ名」とする事もできます。
001
002
003
004
005
006
Sub Main()

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

End Sub

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

 同名の名前空間を複数箇所で宣言することができます。 その場合、そこで宣言されているモジュール・クラスは同じ名前空間に属しているので当然互いに参照することができます。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
025
026
027
028
029
030
Namespace MainNamespace

    Module MainModule

        Sub Main()

            ' ShowMessage()はPublicなのでモジュール名を省略できる
            ShowMessage()

        End Sub

    End Module

End Namespace


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

    Module AnotherModule

        Sub ShowMessage()

            Console.WriteLine("Hello, world")

        End Sub

    End Module

End Namespace
 このコードは次のコードと全く等価です。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
018
019
020
021
022
023
024
Namespace MainNamespace

    Module MainModule

        Sub Main()

            ' ShowMessage()はPublicなのでモジュール名を省略できる
            ShowMessage()

        End Sub

    End Module

    Module AnotherModule

        Sub ShowMessage()

            Console.WriteLine("Hello, world")

        End Sub

    End Module

End Namespace

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

 次のコードのように名前空間の中に名前空間を宣言することもできます。
001
002
003
004
005
006
007
008
009
010
Namespace MainNamespace

    Namespace SubNamespace

        .
        .

    End Namespace

End Namespace
 これは次のようにも表現できます。
001
002
003
004
005
006
Namespace MainNamespace.SubNamespace

    .
    .

End Namespace
 プロジェクトに既定の名前空間が指定されていれば、宣言した名前空間はすべてこの既定の名前空間の中に宣言されたものと同じになります。

名前空間の省略

 深い入れ子関係の名前空間を参照する場合次のように非常にコードが煩雑になります。
001
002
003
004
005
006
007
008
009
010
011
Module MainModule

    Sub Main()

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

    End Sub

End Module
 このような長い名前空間名を毎回記述するのは非常に面倒なのでこれを省略するためにImportキーワードが用意されています。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
' 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というクラスが存在しているとします。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
Namespace SampleNamespace1

    Class SampleClass
    End Class

End Namespace


Namespace SampleNamespace2

    Class SampleClass
    End Class

End Namespace
 そして、この名前空間をインポートしてSampleClassを参照しようとします。
001
002
003
004
005
006
007
008
009
010
011
012
013
' プロジェクトの既定の名前空間から記述する必要があります
Imports SampleConsoleApplication.SampleNamespace1
Imports SampleConsoleApplication.SampleNamespace2

Module SampleModule

    Sub Main()

        Dim s As SampleClass

    End Sub

End Module
 そうすると、このSampleClassはSampleNamespace1のものかSampleNamespace2のものか区別する手段がないので、このコードはコンパイルエラーになります。 こうなると名前の重複を防ぐ目的である名前空間の存在意義がなくなってしまうので、名前空間をインポートした場合でも次のように限密名を指定することで重複を防ぐことができます。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
016
017
' プロジェクトの既定の名前空間から記述する必要があります
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

名前空間のエイリアス

 名前空間をインポートする際に別名(エイリアス)をつけることができます。 これによって長い名前空間の名前を短くして使用することができます。
001
002
003
004
005
006
007
008
009
010
011
012
013
014
015
' 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