VB.NETではブロックレベルでローカル変数を宣言することができます。 ブロックで宣言されたローカル変数はそのブロック内でのみ有効で、ブロックの外や他のブロックからは参照することができません。 宣言された変数が有効である範囲のことをスコープと呼びます。
ブロック
IfステートメントやSelectステートメント、For, For Each, Whileなどの繰り返しのステートメント、Try Catchステートメントなどはローカル変数の有効範囲となるブロックを構成します。
例えば、次のコードで宣言されている二つのローカル変数y
はそれぞれのブロック内でのみ有効で、また互いに独立しています。
1つ目と2つ目のForステートメントはそれぞれ別々のブロックを構成します。 そのため、それぞれのブロック内(Forステートメント内)で宣言されているローカル変数y
は、独立した別々の変数となります。 異なるプロシージャで同名の変数が宣言されていてもそれぞれのプロシージャでは互いに影響しないのと同様、異なるブロックで同名の変数が宣言されていても互いに影響しません。 また、ブロック内で宣言されている変数y
の有効範囲(スコープ)はそのブロック内のみとなるため、ブロック外から変数y
を参照することもできません。
一方、プロシージャ内で宣言されているローカル変数x
は、ブロック外(Forステートメントの外)で宣言されています。 この変数はプロシージャ内の各ブロックから参照することができます。
Forステートメントだけでなく、Ifなど他のステートメントもブロックを構成します。 IfとElseおよびElseIfはそれぞれ別のブロックとなる点に注意してください。
ブロックは階層構造を持ちます。 そのため、入れ子になったステートメントではブロックも入れ子になります。
階層構造の上位にあるブロックから下位のブロックで宣言されている変数は参照できませんが、逆に下位にあるブロックから上位のブロックで宣言されている変数を参照することはできます。 プロシージャ内(ブロック外)で宣言されている変数は階層構造の最上位に位置することになります。
Forステートメントではループ変数の宣言も同時に行えるようになっていますが、この変数もForステートメントが構成するブロック内でのみ有効となります。
ブロック変数と初期値
値を明示的に初期化しないブロック変数は、プロシージャを抜けるまでその値を保持し続ける点に注意が必要です。
この実行結果から分かるとおり、内側のForループを抜けても変数i
の値は保持されています。 毎回初期化するようにするには、次のように変数の宣言と同時に初期化する必要があります。
初期化と宣言の位置が変われば動作も変わるため、ブロック変数を宣言する箇所には注意する必要があります。
空のブロック
CやC#では中括弧{ }
で囲まれた部分がブロックを構成します。 そのため次のように何らかのステートメントを使わなくても変数の有効範囲を限定するための空ブロックを構成することができます。
VB.NETでブロックを構成するにはなんらかのステートメントを使わなければならないので、このような記述をすることができません。
空のブロックを作成する1つの方法として、常に条件式が真となるIfステートメントを使用する方法があります。
このほか、Withステートメントを使用することもできます。
Withステートメントで具体的なオブジェクトを指定する代わりにNothing
や0
、True
/False
などが代用できますが、いずれもWithステートメント内でオブジェクトを参照しなければエラーにはなりません。
ブロックより上位のスコープ
ブロック以外にもスコープを構成する要素には次のようなものが存在します。 また、それぞれの要素はスコープの階層構造の各レベルを構成します。
ブロックより上位のスコープについては、各ページおよびアクセス修飾子を参照してください。