VB.NETでもReDimで配列の大きさを変更したい
はじめに
さて今回は使いどころが正直思いつかないReDim
ステートメントのお話です。
ReDim ステートメント (Visual Basic) | Microsoft Docs
なかなかに翻訳がアレですが、軽く確認した感じ
- 使えるのはプロシージャ(メソッド)内だけ
- 配列のサイズを変えられる
- 1次元ではなく多次元の配列でもつかえる
- ただし内容を保持したままサイズを変更できるのは最終次元のみ
- 配列の次元は変えられない
という事らしいです。
正直多次元配列はあんまり使わないので、1次元配列について軽く見てみようかなと思います。
Let's IL
とりあえずのサンプルコードがこちら
Dim array = New Integer() {1, 2, 3, 4, 5} ReDim Preserve array(10) For Each it In array Console.Write("{0} ", it) Next Console.WriteLine() ReDim Preserve array(3) For Each it In array Console.Write("{0} ", it) Next Console.WriteLine()
それでもって実行結果がこちら
1 2 3 4 5 0 0 0 0 0 0 1 2 3 4
VBでは指定した数+1が配列の要素数になるとか、拡張された領域はデフォルト値で初期化されるとか割とどうでもいい。 私の興味はどのようなILが生成されているのかという事です。
ループのコードが割と邪魔なので、最小の要素のコードで逆アセンブリしてILを見てみます。
Dim array = New Integer() {1, 2, 3, 4, 5} ReDim Preserve array(10) ReDim Preserve array(3)
んで、生成されたILがこちら
.maxstack 3 .locals init ([0] int32[] 'array', [1] int32[] VB$t_array$S0) IL_0000: nop IL_0001: ldc.i4.5 IL_0002: newarr [mscorlib]System.Int32 IL_0007: stloc.1 IL_0008: ldloc.1 IL_0009: ldc.i4.0 IL_000a: ldc.i4.1 IL_000b: stelem.i4 IL_000c: ldloc.1 IL_000d: ldc.i4.1 IL_000e: ldc.i4.2 IL_000f: stelem.i4 IL_0010: ldloc.1 IL_0011: ldc.i4.2 IL_0012: ldc.i4.3 IL_0013: stelem.i4 IL_0014: ldloc.1 IL_0015: ldc.i4.3 IL_0016: ldc.i4.4 IL_0017: stelem.i4 IL_0018: ldloc.1 IL_0019: ldc.i4.4 IL_001a: ldc.i4.5 IL_001b: stelem.i4 IL_001c: ldloc.1 IL_001d: stloc.0 IL_001e: ldloc.0 IL_001f: castclass [mscorlib]System.Array IL_0024: ldc.i4.s 11 IL_0026: newarr [mscorlib]System.Int32 IL_002b: call class [mscorlib]System.Array [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Utils::CopyArray(class [mscorlib]System.Array, class [mscorlib]System.Array) IL_0030: castclass int32[] IL_0035: stloc.0 IL_0036: ldloc.0 IL_0037: castclass [mscorlib]System.Array IL_003c: ldc.i4.4 IL_003d: newarr [mscorlib]System.Int32 IL_0042: call class [mscorlib]System.Array [Microsoft.VisualBasic]Microsoft.VisualBasic.CompilerServices.Utils::CopyArray(class [mscorlib]System.Array, class [mscorlib]System.Array) IL_0047: castclass int32[] IL_004c: stloc.0 IL_004d: nop IL_004e: ret
なんてことのない、VBが内部で新しく配列を作り直してコピーしてるだけでした*1。 『まぁ、そうなるな』以外の感想が出てこない結果ですね。
でもまぁ、一発で配列のサイズを変更できたら使い所によってはかなり便利かもしれませんね。
ちなみに同じ配列ネタとして、レガシーVBでは配列のインデックス範囲を自由に設定できたそうですが、VB.NETではそれは廃止されたそうですね。
( ^o^)ReDim
ステートメントで自由に配列のサイズを変更できるぞ
( ˘⊖˘) 。o(待てよ?List等のコレクションを使えばそもそもサイズとかそこまで気にしなくてもいいはずでは?)
|コーディングガイドライン|┗(☋` )┓三
( ◠‿◠ )☛そこに気づいたか・・・消えてもらう
▂▅▇█▓▒░(’ω’)░▒▓█▇▅▂うわああああああ