How to: Change the Value of a Procedure Argument (Visual Basic)
When you call a procedure, each argument you supply corresponds to one of the parameters defined in the procedure. In some cases, the procedure code can change the value underlying an argument in the calling code. In other cases, the procedure can change only its local copy of an argument.
When you call the procedure, Visual Basic makes a local copy of every argument that is passed ByVal (Visual Basic). For each argument passed ByRef (Visual Basic), Visual Basic gives the procedure code a direct reference to the programming element underlying the argument in the calling code.
If the underlying element in the calling code is a modifiable element and the argument is passed ByRef, the procedure code can use the direct reference to change the element's value in the calling code.
Changing the Underlying Value
To change the underlying value of a procedure argument in the calling code
In the procedure declaration, specify ByRef (Visual Basic) for the parameter corresponding to the argument.
In the calling code, pass a modifiable programming element as the argument.
In the calling code, do not enclose the argument in parentheses in the argument list.
In the procedure code, use the parameter name to assign a value to the underlying element in the calling code.
See the example further down for a demonstration.
Changing Local Copies
If the underlying element in the calling code is a nonmodifiable element, or if the argument is passed ByVal, the procedure cannot change its value in the calling code. However, the procedure can change its local copy of such an argument.
To change the copy of a procedure argument in the procedure code
In the procedure declaration, specify ByVal (Visual Basic) for the parameter corresponding to the argument.
-or-
In the calling code, enclose the argument in parentheses in the argument list. This forces Visual Basic to pass the argument by value, even if the corresponding parameter specifies ByRef.
In the procedure code, use the parameter name to assign a value to the local copy of the argument. The underlying value in the calling code is not changed.
Example
The following example shows two procedures that take an array variable and operate on its elements. The increase procedure simply adds one to each element. The replace procedure assigns a new array to the parameter a() and then adds one to each element.
Public Sub increase(ByVal a() As Long)
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Public Sub replace(ByRef a() As Long)
Dim k() As Long = {100, 200, 300}
a = k
For j As Integer = 0 To UBound(a)
a(j) = a(j) + 1
Next j
End Sub
Dim n() As Long = {10, 20, 30, 40}
Call increase(n)
MsgBox("After increase(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
Call replace(n)
MsgBox("After replace(n): " & CStr(n(0)) & ", " &
CStr(n(1)) & ", " & CStr(n(2)) & ", " & CStr(n(3)))
The first MsgBox call displays "After increase(n): 11, 21, 31, 41". Because the array n is a reference type, replace can change its members, even though the passing mechanism is ByVal.
The second MsgBox call displays "After replace(n): 101, 201, 301". Because n is passed ByRef, replace can modify the variable n in the calling code and assign a new array to it. Because n is a reference type, replace can also change its members.
You can prevent the procedure from modifying the variable itself in the calling code. See How to: Protect a Procedure Argument Against Value Changes (Visual Basic).
Compiling the Code
When you pass a variable by reference, you must use the ByRef keyword to specify this mechanism.
The default in Visual Basic is to pass arguments by value. However, it is good programming practice to include either the ByVal (Visual Basic) or ByRef (Visual Basic) keyword with every declared parameter. This makes your code easier to read.
Security
There is always a potential risk in allowing a procedure to change the value underlying an argument in the calling code. Make sure you expect this value to be changed, and be prepared to check it for validity before using it.
See Also
Tasks
How to: Pass Arguments to a Procedure (Visual Basic)
How to: Protect a Procedure Argument Against Value Changes (Visual Basic)
How to: Force an Argument to Be Passed by Value (Visual Basic)
Concepts
Procedure Parameters and Arguments (Visual Basic)
Passing Arguments by Value and by Reference (Visual Basic)
Differences Between Modifiable and Nonmodifiable Arguments (Visual Basic)
Differences Between Passing an Argument By Value and By Reference (Visual Basic)