Let’s talk about the difference between a reference type and the ByRef modifier on a passed parameter. I’ll start with something simple, an integer.
If you have code like:
dim i as integer = 1 system.debuglog "Before call i = " + str(i) call MyMethod(i) system.debuglog "After call i = " + str(i)
and MyMethod is written as
Sub MyMethod( i as integer ) i = i + 1 system.debuglog CurrentMethodName + " i = " + str(i) End Sub
When you run this code you would see
Before call i = 1
MyMethod i = 2
After call i = 1
Following along, before the call i is set to 1. Then the call is made and because i as not passed ByRef, it is passed by value (ByVal), a copy of the value is sent to MyMethod in a temporary variable also named i – but this a copy not an original.
The method is run, i is altered to be 2 and the message “MyMethod i = 2” printed to the log. Then the method ends, the temporary variable is disposed of and the main code still has the original copy of i so the last message printed showing i is unchanged. To preserve the method’s change back in the caller you need to make the parameter be ByRef and then the actual variable is passed instead of a new temporary being created.
Now let’s apply this same sequence to a reference type like an array:
dim i() as integer = Array(1, 2, 3) system.debuglog "Before call i(0) = " + str(i(0)) + " i(1) = " + str(i(1)) + " i(2) = " + str(i(2)) call MyMethod(i) system.debuglog "After call i(0) = " + str(i(0)) + " i(1) = " + str(i(1)) + " i(2) = " + str(i(2))
and MyMethod is written as
Sub MyMethod( i() as integer ) i = array(10,20,30) system.debuglog CurrentMethodName + " i(0) = " + str(i(0)) + " i(1) = " + str(i(1)) + " i(2) = " + str(i(2)) End Sub
With a reference type (see my earlier post What Kind of Variable Are You if you need any help with that) what we are altering is the contents that are referred to – but not the specific instance that is referred to. So running the code you see this output:
Before call i(0) = 1 i(1) = 2 i(2) = 3 Window1.MyMethod i(0) = 10 i(1) = 20 i(2) = 30 After call i(0) = 1 i(1) = 2 i(2) = 3
So just like with the previous integer example, the reference is not permanently altered despite the effort to do so. Again, in order to change what the parameter refers to you must use ByRef.
If MyMethod were written as such you would be altering the reference that the caller refers to.
Sub MyMethod(byref i() as integer ) i = array(10, 20, 30) system.debuglog CurrentMethodName + " i(0) = " + str(i(0)) + " i(1) = " + str(i(1)) + " i(2) = " + str(i(2)) End Sub
Which is not the same as a reference type. The output of the above method is this:
Before call i(0) = 1 i(1) = 2 i(2) = 3 Window1.MyMethod i(0) = 10 i(1) = 20 i(2) = 30 After call i(0) = 10 i(1) = 20 i(2) = 30