|
-
Feb 24th, 2008, 12:51 PM
#1
Thread Starter
pathfinder
[RESOLVED] Passing Array ByVal
Is there any way to pass an array so that any changes made to it are not returned?
I've always passed arrays byref, and built copies such that any changes made would be upon the copy, to prevent backward propagation errors.
But perhaps I could do it some other way?
I was hoping that ByVal might now work in Net'05, but it still acts like a ByRef when passing arrays.
For example:
Code:
Private Sub TestSortToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TestSortToolStripMenuItem.Click
Dim mArr() As Integer
ReDim mArr(5)
Dim mI As Integer
For mI = 1 To 5
mArr(0) += 1
mArr(mArr(0)) = mI
Next
Call ECHO_IT(mArr)
For mI = 1 To mArr(0)
MessageBox.Show(mArr(mI))
Next
End Sub
Private Sub ECHO_IT(ByVal mArr() As Integer)
Dim mI As Integer
For mI = 1 To mArr(0)
MessageBox.Show(mArr(mI))
mArr(mI) = 0
Next
End Sub
changes the original array.
Is there a better method to pass an array and not return any changes made upon it?
-Lou
-
Feb 24th, 2008, 01:02 PM
#2
Re: Passing Array ByVal
It's working the same as it is supposed to. ByRef and ByVal are internally consistent for all types, this is just one that you get to think through a bit more. When you pass something in ByRef, you are passing the address of an object, while if you pass ByVal, you are passing the object itself. However, for a reference type, such as an array, the object IS just an address, so when you pass it ByRef you are passing the address of the address, while if you pass ByVal you are passing the address. This means that passing a value type ByRef (where you pass the address) is functionally the same as passing a reference type ByVal (again you are just passing the address).
There is no way for MS to "fix" this, because there is no solution that is correct for all cases, and you certainly don't want the behavior to be different for each individual object type.
The problem comes from the fact that if you were really to pass a copy of the array into the function, rather than just passing the address of the array, then the compiler would have to perform an implicit deep copy. After all, what is in the array? What if it was an array of objects that all used a shared database connection? There is no way to decide what needs to be copied in this case. Could the addresses of the objects be copied? Would the objects themselves have to be copied? Would they still share the same DB connection, or would they all get new connections? Since the compiler has no way of answering that question, it doesn't even try.
This does make things consistent, though. If the item is passed ByValue, then a copy of the value is made. If tthe item was just the address of the item, then a copy of the address of the item is made. Quite consistent.
Of course, this means that in your case.....it's business as usual, and always will be.
My usual boring signature: Nothing
 
-
Feb 24th, 2008, 01:06 PM
#3
Re: Passing Array ByVal
An array is really a pointer to the memory address of the first element. So when you're creating an array and passing it to a method like this:
vb Code:
Private Sub MethodA()
Dim intArray() As Integer = {1,2,3,4,5}
MethodB(intArray)
End Sub
Private Sub MethodB(ByVal someArray() As Integer)
For i As Integer = 0 to someArray.GetUpperBound(0)
someArray(i) = 0
Next i
End Sub
You are actually passing a pointer to MethodB. So someArray in MethodB will be pointing to the same memory address as intArray in MethodA.
One workaround to avoid this would be to create a copy of the array and send the copy to the method.
Edit: Dangit. Shaggy Hikers answer is the better one. Read his instead.
-
Feb 24th, 2008, 01:50 PM
#4
Thread Starter
pathfinder
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|