2007.11.29

With Nothingで変数のスコープを限定する

JavaやC#では"{"、"}"で囲むことで変数のスコープをその範囲内に限定することができますが、VB.NETにはそのような書き方はありません。
ただ、実現する方法はいくつかあります。
VB.NETで変数のスコープを限定したい場合、どのような書き方がよいか、その方法を紹介します。

まず、次のようなコードがあるとします。

'東京都のリストを生成
Dim list As New ArrayList
list.Add("千代田区")
list.Add("足立区")
list.Add("品川区")
todofukenList.Add(list)

このコードをコピーして似たようなコードを複数書く場合、次のようになるかと思います。

'東京都のリストを生成
Dim tokyoList As New ArrayList
tokyoList.Add("東京都")
tokyoList.Add("千代田区")
tokyoList.Add("足立区")
tokyoList.Add("品川区")
todofukenList.Add(tokyoList)

'愛知県のリストを生成 Dim aichiList As New ArrayList aichiList.Add("愛知県") aichiList.Add("名古屋市") aichiList.Add("春日井市") todofukenList.Add(aichiList)
'沖縄県のリストを生成 Dim okinawaList As New ArrayList okinawaList.Add("沖縄県") okinawaList.Add("那覇市") okinawaList.Add("名護市") todofukenList.Add(okinawaList)

ここで、間違いやすいミスがあります。
値をセットするListの変数を間違えるということです。
okinawaListに値をセットしているつもりがaichiListに値をセットしていた、というミスがあるかもしれません。

このミスは、変数名を変更しないといけないことで起こるミスで、変更しなければ起きません。
かといって、一度定義した変数を何度も使いまわすのは良くないコードです。
これを解決するには、変数のスコープを限定することです。
スコープを限定することで何度も同じ変数名で定義することができ、それによって変数名も変更する必要がなくなります。

上記の例であれば、todofukenListにセットする部分を関数化(=変数のスコープを関数内に限定)したほうがよいかもしれませんが、コードや内容によっては関数にしないほうが可読性が良くなる場合があります。
関数にしないでスコープを限定する方法として、ステートメントを用いることです。

'東京都のリストを生成
If True Then
    Dim list As New ArrayList
    list.Add("千代田区")
    list.Add("足立区")
    list.Add("品川区")
    todofukenList.Add(list)
End If

このように書いた場合、list変数はIfステートメントの中でしか有効ではありません。
つまり、ステートメントで囲むことによって、スコープを限定することができます。
(基本的な事柄なので、とくに意識しないで使っていることと思います)


では次に考えるのが、どのステートメントを用いるか、ということです。
上記の例はIfステートメントの使い方としては、違和感を感じると思います。
Ifステートメントは条件分岐のために用いるのに、分岐のために使っているわけではないからです。
他のステートメントを考えていくと、

 ・For~Next、While~End While ・・・ 反復処理
 ・Try ・・・ 例外処理
 ・Using ・・・ リソースの解放

とありますが、どれもキーワードを見ただけで処理を連想してしまい、スコープを限定するために用いるステートメントとしては適さないと思います。

そう考えていくと、Withステートメントを用いるのがベターなのではないかと思います。
なぜなら、Withステートメントはコードを省略するために用いるもので、ステートメント自体から処理を連想するものではないからです。
Withの後には変数名が必要ですが、とくに指定するものもないためここではNothingとします。

先ほどのコードをWith Nothingで置き換えると次のようになります。

'東京都のリストを生成
With Nothing
    Dim list As New ArrayList
    list.Add("東京都")
    list.Add("千代田区")
    list.Add("足立区")
    list.Add("品川区")
    todofukenList.Add(list)
End With
    
'愛知県のリストを生成
With Nothing
    Dim list As New ArrayList
    list.Add("愛知県")
    list.Add("名古屋市")
    list.Add("春日井市")
    todofukenList.Add(list)
End With
    
'沖縄県のリストを生成
With Nothing
    Dim list As New ArrayList
    list.Add("沖縄県")
    list.Add("那覇市")
    list.Add("名護市")
    todofukenList.Add(list)
End With

ここで変更すればよいのは、list.Addの中だけです。
このように書くことで、少なくとも変数名を間違えることはなくなります。

開発において、コピーするときに如何にしてミスとなりえる箇所を減らすか、ということも重要になってきます。変数のスコープを限定することは、ミスとなりえる箇所を減らす一つのテクニックといえます。
変数のスコープを限定する方法として、With Nothingを用いることも選択肢の一つとして考えてみてはどうでしょうか。

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

photo
yamaoka