Click here to Skip to main content
16,015,709 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello, all:

I'm new to the VB.NET world and am trying to pass a structure array to a function and have it pass me back a new structure array with update values. Everything in the code below seems to work fine, the returned structure array is perfect, but it also changes the original. What am I doing wrong?!
VB
Public Class Form1
    Structure SpaceCurve
        Dim x As Double
        Dim y As Double
        Dim SpaceName As String
    End Structure
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Dim n As Integer
        'ReDim OrigSC(10)
        Dim OrigSC(10) As SpaceCurve
        Dim WorkSC(10) As SpaceCurve
        For n = 0 To 10
            OrigSC(n).x = n * 1.5
            OrigSC(n).y = n * 2.5
            OrigSC(n).SpaceName = "Space" & CStr(n)
            Console.WriteLine(OrigSC(n).x & "," & OrigSC(n).y & "," & OrigSC(n).SpaceName)
        Next
        WorkSC = UpdateSC(OrigSC, "-test")
        For n = 0 To 10
            Console.WriteLine(WorkSC(n).x & "," & WorkSC(n).y & "," & WorkSC(n).SpaceName)
        Next
        For n = 0 To 10
            Console.WriteLine(OrigSC(n).x & "," & OrigSC(n).y & "," & OrigSC(n).SpaceName)
        Next

    End Sub
    Function UpdateSC(ByVal SCStruct() As SpaceCurve, ByVal SpaceAppend As String) As SpaceCurve()
        Dim x As Integer
        For x = 0 To UBound(SCStruct)
            SCStruct(x).x = 1.0
            SCStruct(x).y = 3.3
            SCStruct(x).SpaceName = SCStruct(x).SpaceName & SpaceAppend
        Next
        UpdateSC = SCStruct
    End Function

End Class


Console...
0,0,Space0
1.5,2.5,Space1
3,5,Space2
4.5,7.5,Space3
6,10,Space4
7.5,12.5,Space5
9,15,Space6
10.5,17.5,Space7
12,20,Space8
13.5,22.5,Space9
15,25,Space10
1,3.3,Space0-test
1,3.3,Space1-test
1,3.3,Space2-test
1,3.3,Space3-test
1,3.3,Space4-test
1,3.3,Space5-test
1,3.3,Space6-test
1,3.3,Space7-test
1,3.3,Space8-test
1,3.3,Space9-test
1,3.3,Space10-test
1,3.3,Space0-test
1,3.3,Space1-test
1,3.3,Space2-test
1,3.3,Space3-test
1,3.3,Space4-test
1,3.3,Space5-test
1,3.3,Space6-test
1,3.3,Space7-test
1,3.3,Space8-test
1,3.3,Space9-test
1,3.3,Space10-test
Posted
Updated 8-May-11 19:27pm
v2
Comments
Sandeep Mewara 9-May-11 1:28am    
Wrapping your code part in PRE tags makes the question readable.

Your structure is a value type, but your array is a reference type. When you pass the array by value, you pass its reference anyway, never the copy of the array. Even though the structure is a value type, it is replaced in the array when you modify it as an array element. Your caller's variable is array, not structure, so the object referenced by this variable (array) is modified.

—SA
 
Share this answer
 
ByVal does not mean what you think!

MSDN[^]

"If you pass a variable argument by value using the ByVal keyword, the procedure cannot modify the variable itself. However, if the argument is a reference type, you can modify the members of the object to which it points, even though you cannot replace the object itself. In particular, you can modify the members of the object. For example, if the argument is an array variable, you cannot assign a new array to it, but you can change one or more of its elements. The changed elements are reflected in the underlying array variable in the calling code."

In your example, UpdateSC cannot change the value of OrigSC, but it can, and does change the values of elements contained within OrigSC

It's like logging in to Windows as a new user: You can't change your old users desktop settings, but you both use the same keyboard!
 
Share this answer
 
Comments
CFConrad 9-May-11 2:31am    
Thank you for your quick response. I've created a temporary structure in the function and return it and everything seems to work fine. -CC
See http://msdn.microsoft.com/en-us/library/aa903253(v=vs.71).aspx[^]

What happens when you pass an object (or any reference type) 'ByVal'?

VB
Sub xxx

 Dim A as MyObj = new MyObj
 MySub(A)

End Sub


Sub MySub (ByVal Param As MyObj)

 Param.Member = NewVal

End Sub



After the MySub call A still points to the same object - and MySub cannot change which object A points to even if it wanted to (if passed ByRef, it could reassign param and so make A point to a completely different MyObj object).

But that does NOT mean that MySub cannot change the values of members of that object - so the code above will change A.Member (A.Member changes - but A doesn't, it is still the same object).

If you want an object with different member values without changing A you need to create a new object within MySub to duplicate the member values first.
 
Share this answer
 
Comments
CFConrad 9-May-11 2:31am    
Your solution worked perfectly, thank you! -CC

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900