VB.NET の関数への引数渡しについて【値型、参照型、ByVal、ByRef】

Visual Basicには関数への引数渡しが4パターンある。

それぞれの違いをまとめておく。

順番に見ていく。

値型の値渡し

Sub FuncValType(ByVal dt As Integer)
    dt = 20
End Sub

Sub Main()
    Dim data As Integer = 10
    Console.WriteLine(data) '10が表示される
    FuncValType(data)
    Console.WriteLine(data) '10が表示される
End Sub

C言語と同様に実引数の値が仮引数にコピーされるため、関数呼び出し後は呼び出し側の実引数dataは変化しない。

値型の参照渡し

Sub FuncValType(ByRef dt As Integer)
    dt = 20
End Sub

Sub Main()
    Dim data As Integer = 10
    Console.WriteLine(data) '10が表示される
    FuncValType(data)
    Console.WriteLine(data) '20が表示される
End Sub

C言語風に考えると実引数のメモリ番地が仮引数にコピーされるため、関数呼び出し後は呼び出し側の実引数dataの値が10から20に更新される。

参照型の値渡し

Class Widget
    Public Property X As Integer
    Public Sub New(ByVal X As Integer)
        Me.X = X
    End Sub
End Class

Sub FuncRefType(ByVal w As Widget)
    w.X = 20 '---- ①
    w = New Widget(30) '---- ②
End Sub

Sub Main()
    Dim data As Widget = New Widget(10)
    Console.WriteLine(data.X) '10が表示される
    FuncRefType(data)
    Console.WriteLine(data.X) '20が表示される
End Sub

この場合、実引数の値であるメモリ内容はメモリ番地になっており、それが仮引数にコピーされるため、実引数dataと仮引数wは同一のインスタンスを参照することになる。上記コードの①のように仮引数w経由でプロパティXを変更すると、その変更は呼び出し側の実引数dataにも影響が及ぶ。ただし②のように仮引数wに新しいインスタンスを代入すると、wとdataは異なるインスタンスを参照することになる。

参照型の参照渡し

Class Widget
    Public Property X As Integer
    Public Sub New(ByVal X As Integer)
        Me.X = X
    End Sub
End Class

Sub FuncRefType(ByRef w As Widget)
    w.X = 20 '---- ①
    w = New Widget(30) '---- ②
End Sub

Sub Main()
    Dim data As Widget = New Widget(10)
    Console.WriteLine(data.X) '10が表示される
    FuncRefType(data)
    Console.WriteLine(data.X) '30が表示される
End Sub

値型の参照渡しと同じくメモリ番地がコピーされるため、実引数dataと仮引数wは同一のインスタンスを参照することになる。そのため上記コードの①のように仮引数w経由でプロパティXを変更すると、その変更は呼び出し側の実引数dataにも影響が及ぶ。ここまでは参照型の値渡しと同じ結果になる。しかし、上記コードの②のように仮引数wに新しく生成されたインスタンスを代入すると、呼び出し側の実引数dataが指し示すインスタンスはwが指し示すインスタンスと同一になる。このとき、もともと実引数dataが参照していたインスタンスはどこからも参照されなくなるため、ガベージコレクション(GC)の対象となる。

ByRefキーワードを付けて定義した仮引数をエイリアス(別名)と考えれば特に問題はないが、今一つイメージできなかったので、以上の通り理解することにした。

※参考書籍

ステップアップ VISUAL BASIC 2010 (MSDNプログラミングシリーズ) | エディフィストラーニング株式会社 矢嶋聡 |本 | 通販 | Amazon
Amazonでエディフィストラーニング株式会社 矢嶋聡のステップアップ VISUAL BASIC 2010 (MSDNプログラミングシリーズ)。アマゾンならポイント還元本が多数。エディフィストラーニング株式会社 矢嶋聡作品ほか、お急ぎ便対象商品は当日お届けも可能。またステップアップ VISUAL BASIC 2010 ...

 

コメント