.NET 広告

【VB.NET】ReDimで配列を拡張した時に起こる問題と、その問題を解決するReDim Preserveについて

記事内に商品プロモーションを含む場合があります

今回はVB.NETで使われるReDimについてお話しします。

VBでは変数を定義する時にDimを使いますが、ReDimというのは、Dimで定義した配列の変数の要素数を変更する(主に配列の拡張)のに利用します。

ただし、このRedimを使う時は一つ問題点があり、注意したいことがあります。

それは、ReDimを使うと、いままでその配列の変数に入れていたデータが初期化されてしまいます

データの初期化をせず、元のデータを保持するのがReDim Preserveです。

実際のコードを見ながら説明していきます。

単純にReDimを使った場合

では早速、以下のようなコードで、配列にデータを入れてReDimで配列を拡張したケースを見てみましょう。

    Private Sub TestRedim()
        '配列を定義
        Dim ArrFruits As String()
        Dim idx As Integer
        ArrFruits = New String() {"パイナップル", "マンゴー", "キウイ", "ライチ", "バナナ"}

        'Redimする前の情報をコンソールに出力する
        Console.WriteLine("ReDimする前の情報" & vbCrLf)
        For idx = 0 To UBound(ArrFruits) Step 1
            Console.WriteLine(idx & "番目は" & ArrFruits(idx) & vbCrLf)
        Next
        Console.WriteLine(vbCrLf)

        '配列の要素数を一つ増やす
        ReDim ArrFruits(5)

        'Redimした後の情報をコンソールに出力する
        ArrFruits(5) = "ドラゴンフルーツ"
        Console.WriteLine("ReDimした後の情報" & vbCrLf)
        For idx = 0 To UBound(ArrFruits) Step 1
            Console.WriteLine(idx & "番目は" & ArrFruits(idx) & vbCrLf)
        Next
    End Sub

最初の定義ではArrFruitsは要素数が5つでしたが、15行目のReDimで要素数を6つに増やしています。

6つ目の要素に「ドラゴンフルーツ」を入れて、配列の中身を表示してみると・・・

最初に入れていたデータがReDimで配列を拡張することで消えてしまいました。

ReDimは配列の中身を初期化するので、元々入れていたデータがすべて消えてしまうのです。

ReDim後に入れた「ドラゴンフルーツ」だけは初期化の対象になっていませんので、正常にデータが格納され、結果にも表示されています。

ReDim Preserveを使った場合

では、上記の処理を以下のようにReDim Preserveを使ったプログラムに書き換えてみます。

    Private Sub TestRedim()
        '配列を定義
        Dim ArrFruits As String()
        Dim idx As Integer
        ArrFruits = New String() {"パイナップル", "マンゴー", "キウイ", "ライチ", "バナナ"}

        'Redimする前の情報をコンソールに出力する
        Console.WriteLine("ReDimする前の情報" & vbCrLf)
        For idx = 0 To UBound(ArrFruits) Step 1
            Console.WriteLine(idx & "番目は" & ArrFruits(idx) & vbCrLf)
        Next
        Console.WriteLine(vbCrLf)

        '配列の要素数を一つ増やす
        ReDim Preserve ArrFruits(5)

        'Redimした後の情報をコンソールに出力する
        ArrFruits(5) = "ドラゴンフルーツ"
        Console.WriteLine("ReDimした後の情報" & vbCrLf)
        For idx = 0 To UBound(ArrFruits) Step 1
            Console.WriteLine(idx & "番目は" & ArrFruits(idx) & vbCrLf)
        Next
    End Sub

ReDim Preserveを利用することで、どのような変化が起きたか、実際の動作を見てみましょう。

最初に入れたデータがReDim Preserveを使うことで、初期化されずに元のデータを保持したまま配列を拡張することが出来ました。

ReDim Preserveを使う機会はVB.NETやVBを使う開発現場では多いと思います。

なぜなら、単純にReDimを使うと配列が初期化されるので、今まで格納していたデータが消えてしまうことは不都合になることが多いからです。

変数の使いまわしのために意図的に配列を初期化するのにReDimは使うことが出来ますが、そもそも変数を使いまわすことは良いプログラムとは言えません(まぁ、For文の中の処理で初期化するというのは一応ありですが)。

なので、配列の拡張のためにReDimを単体で使うことは基本的にあまり推奨しません。

ReDim Preserveを使うことで配列を拡張できることを知っておくと、データを保持したまま動的に配列を拡張できるため、ReDimで配列を初期化する前に別の配列に退避させて、ReDim後に退避させた配列を元に戻すというめんどくさいことをしなくて済みます。

なので、VBやVB.NETで開発を行う場合は、ReDim Preserveを使う知識は必須だと思った方がいいです。

ただ、ReDim Preserveは1次元配列から2次元配列に拡張するなどの次元数を増やす場合に利用することが出来ません

そもそも配列の次元数を増やすことは、ちゃんとしたプログラムを書くとほとんどないので、次元数を増やすのに使えない制約はあまり意識しなくてもいいのではないかと思います。

まとめ

今回は以下のことをお話ししました。

  1. ReDimを使うと配列を拡張できる
  2. ReDimを使うと拡張した配列の中身を初期化する
  3. ReDimの配列の中身を初期化せずに配列を拡張したい場合はReDim Preserveを使う

ReDimはVBやVB.NETで開発していると、配列を動的に拡張したいという場面が出てきます。

ReDimだけの処理、ReDim Preserveと、Preserveをつけた処理、この2つの違いをきちんと理解しておくと、VBやVB.NETで配列関係の誤動作を起こすプログラムは書かなくなります。

今回お話ししたことはVBやVB.NETで開発する場合は必ず覚えておきたい知識になります。

ReDim Preserveを知らずに1行で済むコードを複数行にわたって変なコードを書くことがないよう、きちんと使い方を覚えておきたいところです。

今回の記事はここまでとなります。
また次の記事でお会いしましょう。