投稿者 魔界の仮面弁士  (社会人) 投稿日時 2022/1/18 13:39:32
> VS2019で、web作成の時には、ByValで動いたのですが・・・。
VB6 だろうと VB2022 だろうと、
Web だろうと Console だろうと WinForm だろうと、
すべて同じルールですよ?


ByVal で動いていたというのであれば、その時渡していたのは
Integer などの「構造体」(つまり《値型》)ではなく、
Model などの「クラス」(つまり《参照型》)だったのではないでしょうか。


>>  あるいは《値型》ではなく《参照型》を引数として引き渡し、
>> その参照型のメンバーを編集する方法もあります。これなら ByVal でも動きます。

この辺は基本的な事項なので、一応実験コードを載せておきます。

Public Class Form1
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Me.ListBox1.Items.Clear()

        'Point 構造体を「値渡し」「参照渡し」する実験 
        Dim v1 As New Point(1, 2), v2 As New Point(3, 4)
        Dim v3 As New Point(5, 6), v4 As New Point(7, 8)
        ByValStruct(v1, v2)
        ByRefStruct(v3, v4)
        Me.ListBox1.Items.Add("v1 => " & v1.ToString())  '{X=1,Y=2} のまま変化しない 
        Me.ListBox1.Items.Add("v2 => " & v2.ToString())  '{X=3,Y=4} のまま変化しない 
        Me.ListBox1.Items.Add("v3 => " & v3.ToString())  '{X=400,Y=6} へと書き換わる 
        Me.ListBox1.Items.Add("v4 => " & v4.ToString())  '{X=500,Y=600} に差し替わる 


        'Control クラスを「値渡し」「参照渡し」する実験 
        Dim c1 As Control = Me.Label1  'c1.Text は "Label1" 
        Dim c2 As Control = Me.Label2  'c2.Name は "Label2" 
        Dim c3 As Control = Me.Label3  'c3.Text は "Label3" 
        Dim c4 As Control = Me.Label4  'c4.Name は "Lable4" 
        ByValClass(c1, c2)
        ByRefClass(c3, c4)
        Me.ListBox1.Items.Add("c1 => " & c1.Text)  '"ByValClass" に書き換わる 
        Me.ListBox1.Items.Add("c2 => " & c2.Name)  '"Label2" のまま 
        Me.ListBox1.Items.Add("c3 => " & c3.Text)  '"ByRefClass" に書き換わる 
        Me.ListBox1.Items.Add("c4 => " & c4.Name)  '"Button1" に差し替わる 
    End Sub

    '値型の値渡し 
    Private Sub ByValStruct(ByVal a As Point, ByVal b As Point)
        a.X = 100   'メンバーを書き換える 
        b = New Point(200, 300) '変数の中身そのものを入れ替える 
    End Sub

    '値型の参照渡し 
    Private Sub ByRefStruct(ByRef a As Point, ByRef b As Point)
        a.X = 400   'メンバーを書き換える 
        b = New Point(500, 600) '変数の中身そのものを入れ替える 
    End Sub

    '参照型の値渡し 
    Private Sub ByValClass(ByVal a As Control, ByVal b As Control)
        a.Text = "ByValClass"
        b = Me.Button1 '変数の中身そのものを入れ替える 
    End Sub

    '参照型の参照渡し 
    Private Sub ByRefClass(ByRef a As Control, ByRef b As Control)
        a.Text = "ByRefClass"
        b = Me.Button1 '変数の中身そのものを入れ替える 
    End Sub
End Class




ByVal は「値のコピー」を渡す作業なので、
メソッド側で値型の仮引数を変更しても、呼び出し側の実引数は変化しません。(v1)
メソッド側で値型の仮引数に別の値をセットしても、呼び出し側の変数は差し替わりません。(v2)

ByRef は「元の変数そのもの」の参照が引き渡されるので、
メソッド側で値型の仮引数を変更すると、呼び出し側の実引数も直接変更されます。(v3)
メソッド側で値型の仮引数に別のオブジェクトをセットすると、呼び出し側の変数も差し替わります。(v4)


また、「参照型」はデータの実体(インスタンス)への参照です。
ByRef では「参照情報そのもの」が渡されますが、
ByVal では「参照情報のコピー」が渡されます。

ByVal では、データそのものがコピーされたわけでは無く、
同一データに対する「参照情報」のみがコピーされただけなので、
参照先のデータは完全に同一インスタンスです。

そのため、ByVal でも ByRef でも、メソッド側で参照型オブジェクトのプロパティを書き換えれば、
呼び出し側でも、同一インスタンスのプロパティが書き換わります。(c1、c3)

メソッド側で参照型の仮引数に別のオブジェクトをセットした場合、
ByRef では「元の変数そのもの」の参照情報が差し替わります。(c4)
しかし ByVal では「コピーされた別変数」の参照情報が差し替わるだけなので、
呼び出し元の変数の参照情報は差し替わりません。(c2)