In this Microsoft sample an array Of Doubles is passed to the functions MultiplyMatricesSequential(...)
and MultiplyMatricesParallel(...)
as argument result using ByVal
modifier: http://msdn.microsoft.com/de-de/library/dd460713(v=vs.110).aspx
Values in the arrays are being modified in these functions and the changes are available after the call to the functions returns.
When I change ByVal
to ByRef
in function MultiplyMatricesSequential(...)
nothing changes, when I change to ByRef
in the second function the IDE complains arguments being manipulated in Lambda expressions cannot be passed by reference.
I now wonder how the array values change in the caller when the use of ByVal
is being forced?
When you pass an object ByVal to a function, you put a pointer to it on the stack. Then function can then modify the inner parts of the object, but not replace it with a new object.
When you pass an object ByRef, you instead put a pointer to the objects pointer on the stack. The function can now replace the entire object with a new one.
If you send an intrinsic value, like an Int32
, to a function ByVal the value is put on the stack and can't be edited at all by the function.
The distinction is between "value types" and "reference types". Value types are defined as "Structure" (VB.NET) or "Struct" (C#) whereas reference types are defined as "Class". Primitive types such as integer, double and boolean are value types. Arrays are reference types. As @Mattias Åslund pointed out, whether passed ByVal or ByRef, with reference types you are always passing a pointer.
If you did want to manipulate the passed array but return the original array to the calling procedure, you would need to make a copy into a new locally declared array. Beware of the overhead, however, if passing very large arrays.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim myOriginalArray As String() = New String() {"Hello", "to", "you", "Michael"}
ManipulateArray(myOriginalArray)
MessageBox.Show("myOriginalArray = " & myOriginalArray(0) & " " & myOriginalArray(1) & " " & myOriginalArray(2) & " " & myOriginalArray(3))
End Sub
Private Sub ManipulateArray(ByVal myOriginalArray As String())
Dim myCopyArray(myOriginalArray.GetUpperBound(0)) As String
myOriginalArray.CopyTo(myCopyArray, 0)
myCopyArray(3) = "Sarah"
MessageBox.Show("myCopyArray = " & myCopyArray(0) & " " & myCopyArray(1) & " " & myCopyArray(2) & " " & myCopyArray(3))
End Sub