Groups | Blog | Home
all groups > vb.net upgrade > november 2003 >

vb.net upgrade : Structure Confusion



Darrell Wesley
11/4/2003 6:06:55 AM
IN the help file for VB.net under the heading "Structure
Variables" it states:
You can also assign one variable to another if both are of
the same structure type. This copies all the elements of
one structure to the corresponding elements in the other,
as in the following example:

YourSystem = MySystem
If a structure element is a reference type, such as a
String, Object, or array, the pointer to the data is
copied. If SystemInfo had included an object variable,
then the preceding example would have copied the pointer
from MySystem to YourSystem, and a change to the object's
data through one structure would be in effect when
accessed through the other structure.

But then under the heading "Value Types and Reference
Types" it states:
A data type is a value type if it holds the data within
its own memory allocation. A reference type contains a
pointer to another memory location that holds the data.

Value types include:

All numeric data types
Boolean, Char, and Date
All structures, even if their members are reference types


So the question is which of these statements is correct
when it comes to assigning one structure to another of the
same type as in YourSystem = MySystem. Does this actually
only copy the pointer of MySystem to YourSystem or does it
copy the Values? Does YourSystem.CPU only have a pointer
back to MySystem.CPU or does it contain it's own unique
Darrell Wesley
11/4/2003 9:38:12 AM
I constructed a small test to validate what actually
happens. The structure used looks like this:
Public Structure SomeData
Dim MyName As String
Dim MyChildren() As String
Dim ID As Int16
End Structure

And then I declared 2 other variables:
Dim MyData as SomeData
Dim YourData() as SomeData

ReDim YourData(5)
ReDim MyData.MyChildren(2)
MyData.MyName = "John"
MyData.MyChildren(0) = "Andy"
MyData.MyChildren(1) = "Sally"
MyData.ID = 1
YourData(0) = MyData
YourData(0).MyName = "David"
MyData.ID = 2
YourData(0).ID = 3
YourData(0).MyChildren(0) = "George"
MyData.MyChildren(1) = "Jane"

The result was that MyData.MyChildren(0) = "George" and
YourData().MyChildren(0) = "George" but MyData.MyName
= "John" and YourData(0).MyName = "David". So it looks
like it only copies pointers for those inner arrays and
not strings even though strings are listed as "reference"
types.

[quoted text, click to view]
Darrell Wesley
11/4/2003 11:32:12 AM
So why didn't it create a new string when I did

YourData(0).MyChildren(0) = "George"

In this case when I looked at it MyData.MyChildren(0) had
also changed to "George".

Is there anyway to prevent YourData and MyData from
tracking each other (provided I don't want them to)?


[quoted text, click to view]
Christian_Fröschlin
11/4/2003 4:21:44 PM
[quoted text, click to view]

The first statement is correct, the second one is slighly
misleading. A structure holds its data under its own memory
allocation, but its data may contain a pointer (reference)
which points to data outside its own memory allocation.

Or, to put in another way: When you assign one struct to
another, all values (and pointers) are copied, but not the
objects which are pointed to.

Christian_Fröschlin
11/4/2003 6:54:47 PM
[quoted text, click to view]

YourData(0).MyName = "David"

creates a new string, so the reference in YourData(0) changes.
MyData is still happily referencing the old string "John".

Strings are immutable in .NET
Darrell Wesley
11/5/2003 6:20:52 AM
I have found a way to stop this tracking nature even
though it might be a bit of a cludge way of doing it.

Dim TempData as SomeData
Dim MyData as SomeData
Dim YourData() as SomeData
ReDim YourData(5)
.... set some values in MyData
YourData(0) = MyData
MyData = new SomeData
.... set some new values in MyData
TempData = MyData 'preseve the original values
YourData(1) = MyData
MyData = new SomeData ' breaks the tracking
MyData = TempData ' copy the original values back
TempData = new SomeData

This breaks the tracking and gives YourData(0) and YourData
(1) and MyData their own values at the same time allowing
me to copy the entire structure.

[quoted text, click to view]
Christian_Fröschlin
11/5/2003 10:00:17 AM
[quoted text, click to view]

I *does* create a new string. However, the reference to
the new string is assigned to the single array object
which is shared by MyData and YourData(0), so you
can't expect the array elements to differ ;)

An array is a reference type in .NET

[quoted text, click to view]

Have a look at the Array class and use something like

MyData.MyChildren.CopyTo(YourData(0).MyChildren,0)

(untested)

Note that this will copy the array elements, but not
the objects referenced by array elements (i.e. with
reference types you still have dependencies between
the arrays). In the case of immutable strings this
should not present a problem.
AddThis Social Bookmark Button