3-8 名前空間 (Namespace)

3-8-1 名前空間の定義

プログラムのソースコードを、「名前空間(ネームスペース)」 とよばれるブロックに分割することができます。1 つのプログラムファイルは、複数の名前空間ブロックをもつことができ、また、複数のソースファイルに分割して、1 つの名前空間を構成することもできます。

前項で取り上げた列挙型(Enum)や WinApp2 サンプルプロジェクトにある Form1 クラスなどの型を特定の名前空間の中に定義しておくと、ほかのプログラムと連動する場合、たまたま型の名前が重複してしまうような状況を回避することができます。実は、すでに .NET Framework クラスライブラリに定義されたクラスなどの 「型」 は、特定の名前空間に属しています。

VB .NET において、明示的に名前空間を定義するには、以下のように記述します。

Namespace 名前空間の名前
     : (ネームスペースに属する 「型」 の記述)
End Namespace

Namespace~End Namespace のブロックによって名前空間が構成されます。この内側に、Enum~End Enum の列挙型ブロックや Class~End Class のクラスブロックを定義することができ、定義された型は、この名前空間に属します。この名前空間に属する列挙型 FlyType と、別の名前空間に属する FlyType とは、型の名前が同じでも、名前空間が違うので別の型として認識できます。

[例] FlyType 列挙型を名前空間 MySpace0 の中で定義する

                  
1: Namespace MySpace0
2:     Public Enum FlyType
3:         First
4:         Business
5:         Economy
6:     End Enum
7: End Namespace

このような名前空間ブロックを、1 つのファイルの中に複数書くことができます。また、別々の複数のファイルに、それぞれ同じ名前の名前空間ブロックをつくることができます。ファイルが違っても、名前空間の名前が同じブロックは、1 つの名前空間として扱われます。ただし、あるファイルで Namespace というブロックの宣言をはじめ、別のファイルに End Namespace を書くというように、1 つの Namespace ブロックが複数のファイルにまたぐことはできません。ファイルごとに、Namespace ブロックは閉じている必要があります。

また、名前空間を階層構造にすることもできます。以下のように、1 つの名前空間ブロックの中にネストして(入れ子にして)、子供の名前空間を定義することができます。

[例] 名前空間 MySpace0 の中に、名前空間 Web を定義

                  
1: Namespace MySpace0
2:     NameSpace Web
3:         'ここは名前空間 MySpace0.Web
4:     End Namespace
5: End Namespace

また、次のようにドットをつけて、入れ子の名前空間を表現できます。

[例] MySpace0 の中の Web

                  
1: Namespace MySpace0.Web
2:     'ここは名前空間 MySpace0.Web
3: End Namespace

このような名前空間をうまく利用すると、複数の 「型」 を定義した際に、型の分類、整理にも役立ちます。

3-8-2 暗黙的な名前空間の定義

この章で扱っている WinApp2 プロジェクトの Form1.vb ファイルは、特に名前空間に関する記述はなく、Form1 クラスはどこの名前空間にも属していないようにみえます。しかし、Visual Basic .NET の IDE には、暗黙的に名前空間を定義する機能があります。その設定は、プロジェクトプロパティでおこないます。

設定をおこなうには、まずソリューションエスクプローラのツリーにおいて、プロジェクトを右クリックし、ショートカットメニューから[プロパティ]メニューを選び、プロジェクトプロパティページを開きます(右クリックするのは、ツリーのルートのソリューションではなく、「WinApp2」プロジェクトです)。 プロジェクトプロパティページの左ペインのツリーから、[共有プロパティ]→[全般]タブをクリックすると、右ペインには以下のように表示されます(図 3-19)。この画面での[ルート名前空間]欄に、このプロジェクト全体のソースコードを含む名前空間を指定します。

図 3-19 ルート名前空間の指定

図 3-19 ルート名前空間の指定

つまり、ここで名前空間の名前を指定すると、ソースファイル全体が、その名前をもつ Namespace~End Namespace という大きなブロックに囲まれたことになります。ここでの指定は、そのアプリケーションにとって階層構造の名前空間におけるルートにあたるもので、ソースコードに明示的に名前空間を記述すると、その明示的な名前空間は、このプロパティページで指定したルート名前空間に属する、入れ子の名前空間になります。

WinApp2 プロジェクトのソースコードは、既定ではプロジェクト名のルート名前空間に属します。

このような、ソースコードとして明示的に書かない名前空間の指定は、コマンドラインコンパイラでも可能です。コマンドラインから VB .NET のコンパイルをする場合、以下のようなコマンドオプションとしてルート名前空間を指定します。

[例] MySpace0 をルート名前空間として指定する

                  
D:\Labs> vbc /rootnamespace:MySpace0 MyApp.vb

3-8-3 ドットによる名前空間の指定

ある特定のクラスや列挙型などの 「型」 を参照するとき、その型が自分とは別の名前空間に所属する場合、その型を特定するためには名前空間を特定する必要があります。

以下の例では、列挙型 FlyType の定義(14 行目 ~ 18 行目)と、列挙型を参照する側(6 行目、7 行目)が、それぞれ Util、MySpace という別々の名前空間に属するので、FlyType を使用するためには名前空間を指定する必要があります(WinApp2 プロジェクトの Form1.vb をもとに書き変えたものです。一部省略しています。なお、このソースコードを正しくコンパイルするには、図 3-19 にあるプロパティページにおいて、[スタートアップの設定]欄を、Form1 から MySpace0.Form1 に変更する必要があります。スタートアップの設定については、第 4 章 「さまざまな制御構造」 で扱います)。

                  
 1: Namespace MySpace0  '名前空間 MySpace0
 2:    Public Class Form1
 3:        Inherits System.Windows.Forms.Form
 4:
 5:        Private Sub Button1_Click(... System.Object, ...
 6:            Dim T As Util.FlyType       '別の名前空間の FlyType
 7:            T = Util.FlyType.Business
 8:        End Sub
 9:
10:    End Class
11: End Namespace
12:
13: Namespace Util '名前空間 Util
14:     Public Enum FlyType As Long
15:         First
16:         Business
17:         Ecomomy
18:     End Enum
19: End Namespace

前記の 6 行目では、「Util.FlyType」 というように、名前空間の名前 Util とドットをつけて、列挙型 FlyType を修飾しています。このドットを使うことで、特定の名前空間に属する要素を特定します。

また、3 行目の記述の詳しい内容は、第 5 章 「クラスの定義と実装」 で扱いますが、この行のステートメントにある 「System.Windows.Forms.Form」 という記述は、System という名前空間の中の Windows 名前空間の、さらに内側の Forms 名前空間の中にある Form クラスという意味で、階層構造をなす名前空間を表現している例です。

なお、厳密にいうと、このソースファイルはプロジェクトプロパティの指定によって、暗黙的に WinApp2 というルート名前空間に属しています。よって、6 行目、7 行目のコードを含む Form1 クラスの名前空間は WinApp2.MySpace0 であり、列挙型 FlyType が属する名前空間は、WinApp2.Util ということになります。そのため、以下のように書くこともできます。

[例] 名前空間の完全な指定

                  
6:            Dim T As WinApp2.Util.FlyType
7:            T = WinApp2.Util.FlyType.Business

ただし、6 行目、7 行目のコードが属する MySpace0 名前空間と、FlyType 型が属する名前空間は同じ WinApp2 という名前空間内にあるので、「WinApp2.」 の部分は省略し、相対的な位置を示せばよいのです。

3-8-4 Imports 文による名前空間の指定

Imports ステートメントを使って名前空間の使用を宣言すると、それ以降では、名前空間とドットを使って特定する書き方を省略することができます。

例えば、前項の FlyType 列挙型は、WinApp2.Util の名前空間に属していましたが、あらかじめソースファイルの先頭で 「Imports WinApp2.Util」 と宣言すれば、それ以降では、名前空間 「WinApp2.Util」 の記述を省略することができます。

以下の例は、前項の例に Imports 文を加えたものです。

[例] Imports 文で WinApp2.Util の名前空間を使用することを宣言

                  
 1: Imports WinApp2.Util  '名前空間の使用を宣言
 2:
 3: Namespace MySpace0   '名前空間 MySpace0
 4:    Public Class Form1
 5:        Inherits System.Windows.Forms.Form
 6:
 7:        Private Sub Button1_Click(ByVal sender As System.Object, ...
 8:            Dim T As FlyType   '別の名前空間の FlyType
 9:            T = FlyType.Business
10:        End Sub
11:
12:    End Class
13: End Namespace
14:
15: Namespace Util '名前空間 Util
16:     Public Enum FlyType As Long
17:         First
18:         Business
19:         Ecomomy
20:     End Enum
21: End Namespace

今度の例では、8 行目、9 行目の FlyType には、名前空間とドットによる修飾がありません。Imports 文を使用することで、名前空間の指定を省略することができます。階層構造の深い名前空間にある型を利用する場合、Imports 文を利用することによって、表記がシンプルになります。

Imports ステートメントには、いくつか注意点があります。

Imports ステートメントは、「Option ステートメント」とよばれる記述を除く、その他すべての記述よりも、先に書く必要があります。つまり、そのソースファイルに Option ステートメントがなければ、必ず先頭に書くことになります。もちろん、1つのソースファイルに複数の Imports ステートメントを書くことができます。

また、Imports キーワードに続く名前空間は、いわゆる相対指定ではなく、絶対指定にする必要があります。この例の 1 行目の Imports ステートメントでは、「WinApp2.Util」 と絶対位置を指定しています。一見、暗黙的なルート名前空間の指定が WinApp2 に指定されているのだから、WinApp2 名前空間に属する 1 行目では、相対位置で 「Imports Util」 と書けばよいようにみえますが、あくまで Imports 文は単にそのソースファイルに対して作用する宣言文であり、Imports 文自身が特定の名前空間に属するという概念をもっていません。

ワンポイント

● for VB6

この Imports 文による名前空間の使用は、VB6 の参照設定とは異なります。Imports による宣言は、ソースコードにおいて、ドットによる名前空間の特定を省略して書いてもよいという意味にすぎません。VB .NET の IDE にも、Imports 文とは別に、参照設定という機能があります。また、コマンドラインコンパイラ vbc では、/r オプションが参照設定にあたります。

3-8-5 暗黙的な Imports の指定

Visual Basic .NET の IDE では、ソースコード上に Imports ステートメントを記述する代わりに、プロジェクトプロパティで Imports すべき名前空間を指定することができます。

設定をおこなうには、まずソリューションエスクプローラのツリーにおいて、プロジェクトを右クリックし、ショートカットメニューから[プロパティ]メニューを選び、プロジェクトプロパティページを開きます(右クリックするのは、ツリーのルートのソリューションではなく、「WinApp2」 プロジェクトです)。 プロジェクトプロパティページの左ペインのツリーから、[共有プロパティ]→[インポート]をクリックすると、右ペインには以下のように表示されます(図 3-20)。すでに、いくつかの名前空間について Imports の指定があります。この画面で [名前空間] 欄にインポートしたい名前空間を指定して、インポートの追加 ボタンをクリックすると一覧に追加されます。

図 3-20 Imports の指定

図 3-20 Imports の指定

この指定は、コマンドラインコンパイラ vbc でもおこなうことができます。以下のように、/imports オプションの後ろに名前空間の名前を指定します。

[例] WinApp2.Util 名前空間を指定

                  
D:\Labs> vbc imports:WinApp2.Util MyApp.vb

3-8-6 名前空間(ネームスペース)とアセンブリ

ここで説明した名前空間は、クラスや列挙型などの 「型」 のグルーピングをしたり、複数のファイルから 1 つの名前空間を構成できますが、1-3-2 「アセンブリ(プログラムの最小管理単位)」 で説明したアセンブリとは全く異なる概念です。

名前空間は、プログラム開発者の便宜のために、複数のクラスなどの 「型」 をグルーピングする機能があります。このグルーピングは、論理的なグルーピングであり、コンパイル後の物理ファイルのレベルの分割とは一致しません。1 つの物理ファイルに、複数の名前空間が存在することがあります。1 つの名前空間が、複数のファイルに渡って共有されている場合もあります。

一方、アセンブリは物理的なファイルのグルーピングであり、プログラムファイルの配置をおこなう管理者の便宜のためのグループといえます。1 つのアセンブリは配置をおこなうための最小単位であり、1 つのアセンブリが 1 つだけのファイルのこともあれば、複数のファイルから 1 つのアセンブリを構成する場合もあります。しかし、アセンブリが異なれば、物理ファイルも異なります。

例えば、MyLibs.dll という 1 つのファイルからなるアセンブリがある場合、このファイル名 「MyLibs」 はアセンブリ名です。ただし、このアセンブリ名と名前空間の名前との間には直接的な関係はなく、このファイルの中には、複数の名前空間が含まれているかもしれません。

また、.NET Framework には、String クラスという文字列を扱うクラスがあります。このクラスが属する名前空間は System ですが、この String クラスをもつアセンブリの名前は Mscorlib で、Mscorlib.dll というファイルの中にあり、アセンブリ名と名前空間の名前は一致していません。.NET Framework のクラスライブラリには、アセンブリ名と名前空間の名前が一致する場合もありますが、アセンブリ名と名前空間の名前を一致させることは必須要件ではありません。

<< 前のページ  次のページ>>
目次