ByVal and ByRef with reference type

前端 未结 3 1299
一个人的身影
一个人的身影 2020-12-02 02:04

Please see the code below:

Public Class TypeTest
    Public variable1 As String
End Class

Public Class Form1

    Private Sub Form1_Load(ByVal sender As Obj         


        
相关标签:
3条回答
  • 2020-12-02 02:28

    Since you declared TypeTest as a Class, that makes it a reference type (as opposed to Structure which is used to declare value types). Reference-type variables act as pointers to objects whereas value-type variables store the object data directly.

    You are correct in your understanding that ByRef allows you to change the value of the argument variable whereas ByVal does not. When using value-types, the difference between ByVal and ByRef is very clear, but when you're using using reference-types, the behavior is a little less expected. The reason that you can change the property values of a reference-type object, even when it's passed ByVal, is because the value of the variable is the pointer to the object, not the the object itself. Changing a property of the object isn't changing the value of the variable at all. The variable still contains the pointer to the same object.

    That might lead you to believe that there is no difference between ByVal and ByRef for reference-types, but that's not true. There is a difference. The difference is, when you pass a reference-type argument to a ByRef parameter, the method that you're calling is allowed to change the object to which the original variable is pointing. In other words, not only is the method able to change the properties of the object, but it's also able to point the argument variable to a different object altogether. For instance:

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        Dim t1 As TypeTest = New TypeTest
        t1.Variable1 = "Thursday"
        TestByVal(t1)
        MsgBox(t1.variable1)  ' Displays "Thursday"
        TestByRef(t1)
        MsgBox(t1.variable1)  ' Displays "Friday"
    End Sub
    
    Public Sub TestByVal(ByVal t1 As TypeTest)
        t1 = New TypeTest()
        t1.Variable1 = "Friday"
    End Sub
    
    Public Sub TestByRef(ByRef t1 As TypeTest)
        t1 = New TypeTest()
        t1.Variable1 = "Friday"
    End Sub
    
    0 讨论(0)
  • 2020-12-02 02:34

    A few more examples. One shows ByRef to ByVal forced

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        Dim tt As TypeTest = New TypeTest
        tt.variable1 = "FooBar"
        Debug.WriteLine("'1 " & tt.variable1)
    
        TestByVal1(tt)
        Debug.WriteLine("'2.1 " & tt.variable1)
    
        tt.variable1 = "FooBar"
        TestByVal2(tt)
        Debug.WriteLine("'2.2 " & tt.variable1)
    
        tt.variable1 = "FooBar"
        TestByRef(tt)
        Debug.WriteLine("'3 " & tt.variable1)
    
        tt.variable1 = "FooBar"
        TestByRef((tt)) 'note inner set of () force ref to val
        Debug.WriteLine("'4 " & tt.variable1)
    
        'debug output
        '1 FooBar
        '2.1 FooBar
        '2.2 Monday
        '3 Friday
        '4 FooBar
    End Sub
    
    Public Sub TestByVal1(ByVal t1 As TypeTest)
        t1 = New TypeTest()
        t1.variable1 = "Monday"
    End Sub
    
    Public Sub TestByVal2(ByVal t1 As TypeTest)
        t1.variable1 = "Monday"
    End Sub
    
    Public Sub TestByRef(ByRef t1 As TypeTest)
        t1 = New TypeTest()
        t1.Variable1 = "Friday"
    End Sub
    
    0 讨论(0)
  • 2020-12-02 02:35

    ByVal actually copies the value of the current variable and pass it to the function. By reference copies the current reference to the function. Let's take your example:

    t1 is a reference variable which contains the address of the object of type TypeTest, so when you use ByVal, the address is copied to the function. Eventually you use the same object.

    Where it really makes sense is, in case of basic variables like int, float etc.

    Example: Int temp =0;

    temp is a variable which contains the value 0, so when copied 0 is passed. If you use reference then address of temp is passed (&0) to the function.

    To summarize, ByRef makes more sense only in the basic types and not complex types.

    0 讨论(0)
提交回复
热议问题