VBとC#は兄弟言語ですが、C#から見ると引っ掛かりやすい点があって、ぱっと思いつく限り以下のようなものがあります。
- Nothingの意味(必ずしもnullではない)
- 配列のコンストラクタの要素数
- 整数と実数の自動変換(とくに除算時)
- オーバーロード解決の優先順
以下のメソッド中のローカル変数valueについて、LocalVariableCase0では初期値としてFalseを代入しているのに対し、LocalVariableCase1では初期値を代入していませんが、Boolean型の既定値がFalseなので同じ結果になります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Private Sub LocalVariableCase0() | |
Dim value As Boolean = False | |
Console.WriteLine(value) | |
value = True | |
'False | |
End Sub | |
Private Sub LocalVariableCase1() | |
Dim value As Boolean | |
Console.WriteLine(value) 'No error in VB | |
value = True | |
'False | |
End Sub |
以下のLocalVariableCase2ではループが回る度にvalueはFalseに初期化されますが、LocalVariableCase3ではループしても前回のループで与えられたTrueが残ってしまいます。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Private Sub LocalVariableCase2() | |
For i = 0 To 2 | |
Dim value As Boolean = False | |
Console.WriteLine(value) | |
value = True | |
Next | |
'False | |
'False | |
'False | |
End Sub | |
Private Sub LocalVariableCase3() | |
For i = 0 To 2 | |
Dim value As Boolean | |
Console.WriteLine(value) 'No error in VB | |
value = True | |
Next | |
'False | |
'True | |
'True | |
End Sub |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Private Sub LocalVariableCase4A() | |
For i = 0 To 2 | |
LocalVariableCase4B() | |
Next | |
'False | |
'False | |
'False | |
End Sub | |
Private Sub LocalVariableCase4B() | |
Dim value As Boolean | |
Console.WriteLine(value) 'No error in VB | |
value = True | |
End Sub |
これは少しトリッキーというか、予想とは違っていて驚いたわけですが、そういえばVBを勉強し始めたときに変数に初期値を与えておかないと予期しない動作になって危ないと読んだような記憶がありますが、すっかり忘れてました。
というか、何でもかんでも初期値を与えるのもカーゴカルトみたいで無駄だなと思って削っていたら引っ掛かってしまったわけですが、また忘れそうなので書いておきます。
[追記] IL
これだけでは何がどうなっているか明瞭でないので、LocalVariableCase3のILをIL DASMで見ると、こうなっています。

これも今更ですが、ローカル変数はVBでのメソッド中の位置に関わらずILでは冒頭で宣言される形になっています。そこでVBでもローカル変数を冒頭で宣言するように変えたメソッドを作り、そのILを見たのが以下です。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Private Sub LocalVariableCase5() | |
Dim i As Integer | |
Dim value As Boolean | |
For i = 0 To 2 | |
Console.WriteLine(value) 'No error in VB | |
value = True | |
Next | |
'False | |
'True | |
'True | |
End Sub |

見ての通り、ILは全く同じになります。つまり、ローカル変数の宣言はその位置で変数が初めて確保されることを意味しないので、初期値にリセットするにはきちんと代入しないとダメということですね。
0 コメント :
コメントを投稿