次の方法で共有


Visual Basic のスコープ

宣言された要素の スコープ は、名前を修飾したり 、Imports ステートメント (.NET 名前空間と型) で使用したりせずに参照できるすべてのコードのセットです。 要素は、次のいずれかのレベルでスコープを持つことができます。

レベル 説明
ブロック スコープ 宣言されているコード ブロック内でのみ使用できます
プロシージャ スコープ 宣言されているプロシージャ内のすべてのコードで使用できます
モジュール スコープ 宣言されているモジュール、クラス、または構造体内のすべてのコードで使用できます
名前空間スコープ 宣言されている名前空間内のすべてのコードで使用できます

これらのスコープ レベルは、最も狭い (ブロック) から最も広い (名前空間) まで進行します。最 も狭いスコープ は、修飾なしで要素を参照できる最小のコード セットを意味します。 詳細については、このページの「スコープのレベル」を参照してください。

スコープの指定と変数の定義

要素のスコープは、宣言時に指定します。 スコープは、次の要因によって異なります。

  • 要素を宣言する領域 (ブロック、プロシージャ、モジュール、クラス、または構造体)

  • 要素の宣言を含む名前空間

  • 要素に対して宣言するアクセス レベル

同じ名前でスコープが異なる変数を定義する場合は注意が必要です。これにより、予期しない結果が発生する可能性があるためです。 詳細については、「 宣言された要素への参照」を参照してください。

スコープのレベル

プログラミング要素は、宣言するリージョン全体で使用できます。 同じリージョン内のすべてのコードは、名前を修飾せずに要素を参照できます。

ブロック スコープ

ブロックは、次のような開始および終了宣言ステートメント内で囲まれたステートメントのセットです。

  • DoLoop

  • For [Each] と Next

  • IfEnd If

  • SelectEnd Select

  • SyncLockEnd SyncLock

  • TryEnd Try

  • WhileEnd While

  • WithEnd With

ブロック内で変数を宣言する場合は、そのブロック内でのみ使用できます。 次の例では、整数変数 cube のスコープは IfEnd Ifの間のブロックであり、実行がブロックから渡されたときに cube を参照できなくなります。

If n < 1291 Then
    Dim cube As Integer
    cube = n ^ 3
End If

変数のスコープがブロックに制限されている場合でも、その有効期間はプロシージャ全体の有効期間です。 プロシージャ中にブロックを複数回入力した場合、各ブロック変数は前の値を保持します。 このような場合の予期しない結果を回避するには、ブロックの先頭でブロック変数を初期化することをお勧めします。

プロシージャ スコープ

プロシージャ内で宣言された要素は、そのプロシージャの外部では使用できません。 宣言を含むプロシージャのみが使用できます。 このレベルの変数は、 ローカル変数とも呼ばれます。 Dim ステートメントを使用して、Static キーワードの有無にかかわらず宣言します。

プロシージャスコープとブロックスコープは密接に関連しています。 プロシージャ内で変数を宣言するが、そのプロシージャ内のブロックの外側にある場合、その変数はブロック スコープを持つものとして考えることができます。ブロックはプロシージャ全体です。

すべてのローカル要素は、 Static 変数であっても、それらが出現するプロシージャに対してプライベートです。 プロシージャ内で Public キーワードを使用して要素を宣言することはできません。

モジュール スコープ

便宜上、単一用語 モジュール レベル は、モジュール、クラス、および構造体に等しく適用されます。 このレベルで要素を宣言するには、宣言ステートメントをプロシージャまたはブロックの外部に配置し、モジュール、クラス、または構造体内に配置します。

モジュール レベルで宣言を行うと、選択したアクセス レベルによってスコープが決まります。 モジュール、クラス、または構造体を含む名前空間もスコープに影響します。

プライベート アクセス レベルを宣言する要素は、そのモジュール内のすべてのプロシージャで使用できますが、別のモジュールのコードでは使用できません。 アクセス レベルのキーワードを使用しない場合、モジュール レベルの Dim ステートメントは既定で Private されます。 ただし、Dim ステートメントで Private キーワードを使用することで、スコープとアクセス レベルをより明確にすることができます。

次の例では、モジュールで定義されているすべてのプロシージャが文字列変数 strMsgを参照できます。 2 番目のプロシージャが呼び出されると、ダイアログ ボックスに strMsg 文字列変数の内容が表示されます。

' Put the following declaration at module level (not in any procedure).
Private strMsg As String
' Put the following Sub procedure in the same module.
Sub initializePrivateVariable()
    strMsg = "This variable cannot be used outside this module."
End Sub
' Put the following Sub procedure in the same module.
Sub usePrivateVariable()
    MsgBox(strMsg)
End Sub

名前空間スコープ

Friend キーワードまたは Public キーワードを使用してモジュール レベルで要素を宣言すると、その要素が宣言されている名前空間全体のすべてのプロシージャで使用できるようになります。 前の例に対する次の変更により、 strMsg 文字列変数は、その宣言の名前空間内の任意の場所のコードで参照できます。

' Include this declaration at module level (not inside any procedure).
Public strMsg As String

名前空間スコープには、入れ子になった名前空間が含まれます。 名前空間内から使用可能な要素は、その名前空間内で入れ子になった名前空間内からも使用できます。

プロジェクトに Namespace ステートメントが含まれていない場合、プロジェクト内のすべてのものが同じ名前空間内にあります。 この場合、名前空間スコープはプロジェクト スコープと考えることができます。 Public モジュール、クラス、または構造体の要素は、プロジェクトを参照するすべてのプロジェクトでも使用できます。

スコープの選択

変数を宣言するときは、スコープを選択するときに次の点に注意する必要があります。

ローカル変数の利点

ローカル変数は、次の理由から、任意の種類の一時的な計算に適しています。

  • 名前の競合回避。 ローカル変数名は競合の影響を受けにくい。 たとえば、 intTemp という変数を含む複数の異なるプロシージャを作成できます。 各 intTemp がローカル変数として宣言されている限り、各プロシージャは独自のバージョンの intTempのみを認識します。 どのプロシージャでも、他のプロシージャの変数に影響を与えることなく、ローカル intTempintTemp値を変更できます。

  • メモリ消費量。 ローカル変数は、プロシージャの実行中にのみメモリを消費します。 プロシージャが呼び出し元のコードに戻ると、メモリが解放されます。 これに対し、 共有 変数と 静的 変数は、アプリケーションの実行が停止するまでメモリ リソースを消費するため、必要な場合にのみ使用します。 インスタンス変数 は、インスタンスが存在し続けている間にメモリを消費するため、ローカル変数よりも効率が低くなりますが、 SharedStatic 変数よりも効率的になる可能性があります。

スコープの最小化

一般に、変数または定数を宣言するときは、スコープをできるだけ狭くすることをお勧めします (ブロック スコープは最も狭くなります)。 これにより、メモリを節約し、コードが誤って間違った変数を参照する可能性を最小限に抑えることができます。 同様に、変数は、プロシージャ呼び出し間で値を保持する必要がある場合にのみ 静的 として宣言する必要があります。

こちらも参照ください