同じ名前を持つ複数の変数がある場合に参照を解決する

更新 : 2007 年 11 月

コンパイラでは、名前の参照を名前の宣言に対応させようとするとき、最も狭いスコープの中で一致する宣言を検索します。これは、この参照が行われているコードを起点として、起点を含んでいる最も内側のコンテナ要素から外側のレベルへと順に検索範囲を拡大していくことを意味します。

この検索処理をオーバーライドし、より広いスコープで宣言されている名前を指定する場合には、より広いスコープを持つコンテナ要素によって変数名を修飾する必要があります。場合によっては、コンテナ要素をさらに修飾する必要もあります。名前の修飾の詳細については、「方法 : 宣言された要素名を修飾する」を参照してください。

同じ名前を持つ複数のプログラミング要素にアプリケーションからアクセスする場合にも、名前参照の修飾が必要になることがあります。例については、このヘルプ ページの「同じ名前のクラス」および「方法 : 同じ名前を持つ 2 つの要素を区別する」を参照してください。

最も狭いスコープ

次の例は、同じ名前を持つ 2 つの変数への参照を示します。

' Assume these two modules are both in the same assembly.
Module container
    Public totalCount As Integer = 1
    Public Sub showCount()
        Dim totalCount As Integer = 6000
        ' The following statement displays the local totalCount (6000).
        MsgBox("Unqualified totalCount is " & CStr(totalCount))
        ' The following statement displays the module's totalCount (1).
        MsgBox("container.totalCount is " & CStr(container.totalCount))
    End Sub
End Module
Module callingModule
    Public Sub displayCount()
        container.showCount()
        ' The following statement displays the containing module's totalCount (1).
        MsgBox("container.totalCount is " & CStr(container.totalCount))
    End Sub
End Module

上の例では、同じ totalCount という名前を持ち、container モジュール内でのスコープ レベルが異なる 2 つの変数を宣言しています。showCount プロシージャで、修飾しないで totalCount を表示すると、Visual Basic コンパイラは、最も狭いスコープの宣言、つまり showCount 内でローカル宣言されている変数に参照を解決します。コンテナであるモジュール container で totalCount を修飾すると、コンパイラは参照を広いスコープの宣言に解決します。

別のコンテナ要素のメンバ

他のクラスや構造体の非共有メンバを使用するときには、最初に、クラスや構造体のインスタンスを指す変数または式でメンバ名を修飾する必要があります。次の例の demoClass は、class1 というクラスのインスタンスです。

Dim demoClass As class1 = New class1()
demoClass.someSub[(argumentlist)]

共有 (Shared (Visual Basic)) ではないメンバを修飾するときは、クラス名自体を使用することはできません。最初に、オブジェクト変数 (この場合は demoClass) 内にインスタンスを作成する必要があります。次に、その変数名でこのインスタンスを参照します。

クラスまたは構造体に Shared メンバがある場合、そのメンバは、クラスまたは構造体の名前で修飾することも、インスタンスを指す変数または式で修飾することもできます。

モジュールには個別のインスタンスがありません。モジュールのすべてのメンバは、既定で Shared です。したがって、モジュール メンバはモジュール名で修飾します。

参照の修飾例

モジュール メンバ プロシージャに対する参照を修飾する例を次に示します。

' Assume these three modules are all in the same assembly.
Module module1
    Public Sub perform()
        MsgBox("module1.perform() now returning")
    End Sub
End Module
Module module2
    Public Sub perform()
        MsgBox("module2.perform() now returning")
    End Sub
    Public Sub doSomething()
        ' The following statement calls perform in module2, the active module.
        perform()
        ' The following statement calls perform in module1.
        module1.perform()
    End Sub
End Module
Module module3
    Public Sub callPerform()
        ' The following statement calls perform in module1.
        module1.perform()
        ' The following statement makes an unresolvable name reference
        ' and therefore generates a COMPILER ERROR.
        perform() ' INVALID statement
    End Sub
End Module

前の例では、同じ perform という名前を持ち、プロジェクト内の別々のモジュールにある 2 つの Sub プロシージャを宣言しています。どちらのプロシージャについても、宣言されたモジュール内で指定するときには修飾子を必要としませんが、それ以外の場所から参照するときには修飾子が必要です。module3 内にある最後の参照では、perform が修飾されていないため、コンパイラはこの参照を解決できません。

プロジェクトへの参照

別のプロジェクトで定義されている Public (Visual Basic) 要素を使用するには、最初にプロジェクトのアセンブリまたはタイプ ライブラリへの参照を設定する必要があります。参照を設定するには、[プロジェクト] メニューの [参照の追加] をクリックするか、コマンド ラインで /reference (Visual Basic) コンパイラ オプションを使用します。

たとえば、.NET Framework の XML オブジェクト モデルを使用できます。System.Xml 名前空間への参照を設定すると、XmlDocument など、この名前空間にあるすべてのクラスを宣言し、使用できます。XmlDocument の使用方法を次の例に示します。

' Assume this project has a reference to System.Xml
' The following statement creates xDoc as an XML document object.
Dim xDoc As System.Xml.XmlDocument

コンテナ要素のインポート

Imports ステートメント (.NET 名前空間および型) を使うと、使用するモジュールやクラスを含む名前空間をインポートできます。インポートした名前空間で定義されている要素は、名前を完全修飾せずに参照できます。次の例では、前の例を書き直して System.Xml 名前空間をインポートしています。

' Assume this project has a reference to System.Xml
' The following statement must precede all your declarations.
Imports System.Xml
' The following statement creates xDoc as an XML document object.
Dim xDoc As XmlDocument

また、Imports ステートメントでは、インポートする各名前空間のインポート エイリアスを定義することもできます。インポート エイリアスを使用すると、ソース コードが短くてわかりやすいものになります。次の例では、前の例を書き直して、System.Xml 名前空間のエイリアスとして xD を使用しています。

' Assume this project has a reference to System.Xml
' The following statement must precede all your declarations.
Imports xD = System.Xml
' The following statement creates xDoc as an XML document object.
Dim xDoc As xD.XmlDocument

Imports ステートメントを指定しても、他のプロジェクトの要素をアプリケーションで使用できるようになるわけではありません。つまり、参照を設定する代わりになるわけではありません。名前空間をインポートした場合は、その名前空間で定義されている名前に修飾子を付ける必要がなくなるだけです。

Imports ステートメントを使って、モジュール、クラス、構造体、および列挙値をインポートすることもできます。インポートした要素のメンバは、修飾子を付けずに使用できます。ただし、クラスや構造体の非共有メンバについては、常に、クラスまたは構造体のインスタンスになる変数または式を使って修飾する必要があります。

同じ名前のクラス

オブジェクトの新しいインスタンスを作成するときには、所属する名前空間やタイプ ライブラリでクラスを修飾することが必要となる場合もあります。たとえば、System.Windows.Forms 名前空間と System.Web.UI.WebControls 名前空間の両方に Label クラスが含まれています (System.Windows.Forms.LabelSystem.Web.UI.WebControls.Label)。アプリケーションで両方のクラスを使用する場合、またはアプリケーション独自の Label クラスを定義する場合は、それぞれの Label オブジェクトを区別する必要があります。変数の宣言に名前空間を含めるか、エイリアスをインポートします。次の例では、インポート エイリアスを使用しています。

' The following statement must precede all your declarations.
Imports win = System.Windows.Forms, web = System.Web.UI.WebControls
' The following statement references the Windows.Forms.Label class.
Dim winLabel As New win.Label()

名前付けのガイドライン

同じ名前を持つ複数のプログラミング要素を定義すると、コンパイラがその名前への参照を解決しようとするときに、名前のあいまいさの問題が発生する可能性があります。スコープ内に複数の定義がある場合、またはスコープ内に定義がない場合、参照は解決できません。例については、このヘルプ ページの「参照の修飾例」を参照してください。

名前のあいまいさを回避するには、すべての要素に一意の名前を付けます。そうすることで、名前空間、モジュール、またはクラスによって名前を修飾することなく、任意の要素を参照できます。また、誤って異なる要素を参照する可能性も少なくなります。

参照

処理手順

方法 : プロジェクト プロパティおよび構成設定を変更する

方法 : 宣言された要素名を修飾する

方法 : 同じ名前を持つ 2 つの要素を区別する

概念

Visual Basic における変数

参照

Imports ステートメント (.NET 名前空間および型)

New (Visual Basic)

Public (Visual Basic)

その他の技術情報

宣言された要素の参照