Visual Basic 2008(というか.NET Frameworkというか)で配列の型を調べてみた。

えーと、配列を宣言するとき、書き方が何通りかあるんだよね。で、それって具体的に何がどう違うの?というのをちょっと調べてみた。

Module Module1
    Sub Main()
        Dim hoge() As Byte = {}
        Dim fuga As Byte() = {}
        Dim piyo = Array.CreateInstance(GetType(Byte), 0)
        Dim foo As New List(Of Byte)
        System.Console.WriteLine("hoge's TypeName is {0}.", hoge.GetType.ToString)
        System.Console.WriteLine("fuga's TypeName is {0}.", fuga.GetType.ToString)
        System.Console.WriteLine("piyo's TypeName is {0}.", piyo.GetType.ToString)
        System.Console.WriteLine("foo's TypeName is {0}.", foo.GetType.ToString)
        Array.Resize(hoge, 3)
        hoge(0) = 1
        hoge(1) = 2
        hoge(2) = 3
        fuga = hoge
        piyo = hoge
        foo = hoge.ToList
        hoge(1) = 255
        System.Console.WriteLine("hoge(1)={0},fuga(1)={1},piyo(1)={2},foo(1)={3}", hoge(1), fuga(1), piyo(1), foo(1))
    End Sub
End Module

これの出力結果はこうなる。

hoge's TypeName is System.Byte.
fuga's TypeName is System.Byte.
piyo's TypeName is System.Byte[].
foo's TypeName is System.Collections.Generic.List`1[System.Byte].
hoge(1)=255,fuga(1)=255,piyo(1)=255,foo(1)=2

なんと、hoge,fuga,piyoはまったく同じ型になる。なので、そのまま代入文とか実行可能。但し、ジェネリック型のListは型が違う。なので単純な代入はNGでToListしないと配列からは代入できなかった。
じゃあ、Listジェネリックから配列への代入は? ということで下の2行を追加してみる。

        hoge = foo.ToArray
        System.Console.WriteLine("hoge(1)={0},fuga(1)={1},piyo(1)={2},foo(1)={3}", hoge(1), fuga(1), piyo(1), foo(1))

これの出力結果はこうなる。

hoge(1)=2,fuga(1)=255,piyo(1)=255,foo(1)=2

hogeにはfoo.ToArrayで新たに生成されたSystem.Byte[]型のインスタンスへの参照にすげ変わる。fugaとpiyoが持っている参照は破壊されない。基本なんだけど、このへんうっかりすると勘違いしてしまうからなー。気をつけないと。このあたり、参照型のモノを引数で関数なりサブルーチンに渡すときの感覚が値型と違う!ということにつながってくるんだけど、まあ、それはまた別途書いてみようかなと。