Difference between ByVal and ByRef?

2020-02-09 07:16发布

What is the difference? I always use ByVal, but, I don't really have a good idea of when should I and when not...

9条回答
Juvenile、少年°
2楼-- · 2020-02-09 07:42

I will try to explain the difference in simple words.

  • passing argument by value makes it input only parameter. This is the safest way, therefore is used by default in 95% of the cases.

  • passing argument by reference makes it both input and output parameter. The output parameter can be changed inside the function which creates a rarely used side-effect.

查看更多
啃猪蹄的小仙女
3楼-- · 2020-02-09 07:45

I know this question has pretty much been answered, but I just wanted to add the following...

The object you pass to a function is subject to ByRef/ByVal, however, if that object contains references to other objects, they can be modified by the called method regardless of ByRef/ByVal. Poor explanation, I know, see code below for a better understanding:

Public Sub Test()
    Dim testCase As List(Of String) = GetNewList()
    ByRefChange1(testCase)
    'testCase = Nothing
    testCase = GetNewList()

    ByValChange1(testCase)
    'testCase is unchanged
    testCase = GetNewList()

    ByRefChange2(testCase)
    'testCase contains the element "ByRef Change 2"
    testCase = GetNewList()

    ByValChange2(testCase)
    'testCase contains the element "ByVal Change 2"

End Sub

Public Function GetNewList() As List(Of String)
    Dim result As List(Of String) = New List(Of String)
    result.Add("Value A")
    result.Add("Value B")
    result.Add("Value C")
    Return result
End Function

Public Sub ByRefChange1(ByRef aList As List(Of String))
    aList = Nothing
End Sub

Public Sub ByValChange1(ByVal aList As List(Of String))
    aList = Nothing
End Sub

Public Sub ByRefChange2(ByRef aList As List(Of String))
    aList.Add("ByRef Change 2")
End Sub

Public Sub ByValChange2(ByVal aList As List(Of String))
    aList.Add("ByVal Change 2")
End Sub

EDIT:

Also, consider if this function was called:

Public Sub ByValChange3(ByVal aList As List(Of String))
    aList.Add("ByVal Change 3")
    aList = New List(Of String)
    aList.Add("ByVal Change 4")
End Sub

What happens in this case is "ByVal Change 3" is added to the callers list, but at the point you specify that "aList = New List" you are then pointing the new reference, to a new object, and become detached from the callers list. Both common sense and might catch you out one day, so something to bear in mind.

查看更多
Animai°情兽
4楼-- · 2020-02-09 07:46

Think there may have been a typo in the last sample: The last sub should be "byval" and not "byref". :)

Also added a msgbox statement in trying_byval so you can understand what is meant.

Sub begin()
Dim last_column As Integer

last_column = 234
MsgBox "Begin:" & last_column

trying_byref x:=last_column
MsgBox "byref:" & last_column

trying_byval v:=last_column
MsgBox "byval:" & last_column
End Sub

Sub trying_byref(ByRef x)
x = 111
End Sub

Sub trying_byval(ByVal v)  '<--not ByRef, that was in sub trying_byref.
v = 222
MsgBox "In Here:" & v
End Sub
查看更多
登录 后发表回答