Related collections of objects

  • Thread starter Thread starter Guest
  • Start date Start date
G

Guest

I’m in need of some remedial instruction collections of objects. I doubt if
this question is specific to pocket pc and VB, but that’s where I’m coding.

When I create a collection, call it collection A, and then create a new
collection B, if I make a change to one of the items in collection B, the
exact same changes effect collection A. While I could see this as being a
feature, for what I’m doing… well, I wish it wouldn’t. Is there some simple
way that I can “sever†the linkage between these two collections?
Here’s an example of the problem

Dim Vegetables As New Collection
Dim NewVegetables As New Collection

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
LoadVeggies()
NewVegetables = Vegetables
Dim Vegetable0 As New Vegetable
For Each Vegetable0 In NewVegetables
If Vegetable0.Name = "Squash" Then
Vegetable0.Color = "Green"
End If
Next
End Sub
Private Sub LoadVeggies()
Dim vegetableA As New Vegetable
vegetableA.Name = "Carrot"
vegetableA.Color = "Orange"
Vegetables.Add(vegetableA)

Dim vegetableB As New Vegetable
vegetableB.Name = "Squash"
vegetableB.Color = "Yellow"
Vegetables.Add(vegetableB)

End Sub
End Class
In this code, when I set a brake pt at the end sub for the Form 1 load, I’d
like to see the If logic create only a green Squash in NewVegetables. The
Yellow Squash should stay in Vegetables. It doesn’t, I get a green squash in
both collections. Some how the two collections are linked and I need to
sever the link. Suggestions?
 
Your problem is that you set NewVegetables equal to Vegetables. Because
they are not 'simple' types (like a string or integer), a reference is
made to the original rather than a copy being made. Here is an
optimization of your code with the fix:

Dim Vegetables As New Collection
Dim NewVegetables As New Collection

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
LoadVeggies()
For Each Veg as Vegetable In Vegetables
NewVegetables.Add(Veg)
Next
Vegetables.Clear
For Each Vegetable0 As Vegetable In NewVegetables
If Vegetable0.Name = "Squash" Then
Vegetable0.Color = "Green"
End If
Next
End Sub
Private Sub LoadVeggies()
Dim vegetableA As New Vegetable
vegetableA.Name = "Carrot"
vegetableA.Color = "Orange"
Vegetables.Add(vegetableA)

Dim vegetableB As New Vegetable
vegetableB.Name = "Squash"
vegetableB.Color = "Yellow"
Vegetables.Add(vegetableB)

End Sub
End Class
 
Matt thanks, but I tried your code sample, and still got a bad result.
Collection "vegtables" was identical to collection "newvegtables".... both
contained "green squash" when only "newvegtables" should have.

I tried this where i started, as a pocketpc ap, and then again as a windows
ap.

something that might be telling: "Vegtables.clear" as a command was
rejected on my system as a valid command. perhaps we have different
environments?

hmmm.... any guidance would be appreciated
 
You have duplicated the same problem. Your For loop simply copies the
references to the new vegetable collection.
 
Dave J wrote:

What Matt said is correct.
Dim Vegetables As New Collection
Dim NewVegetables As New Collection

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As
System.EventArgs) Handles MyBase.Load
LoadVeggies()
NewVegetables = Vegetables

The line above simply assigns the reference to the Vegetable collection
to the NewVegetables collection. In other words, they both point to
the *same* collection. You need this line:

NewVegetables = New VegetableCollection

Do as Matt suggested but make sure you are making copies of the
vegetable objects by adding a Clone method to your Vegetable class (see
below):

For Each v As Vegetable In Vegetables
Dim NewVeg As Vegetable = v.Clone
NewVegetables.Add(NewVeg)
Next
Dim Vegetable0 As New Vegetable
For Each Vegetable0 In NewVegetables
If Vegetable0.Name = "Squash" Then
Vegetable0.Color = "Green"
End If
Next
End Sub
Private Sub LoadVeggies()
Dim vegetableA As New Vegetable
vegetableA.Name = "Carrot"
vegetableA.Color = "Orange"
Vegetables.Add(vegetableA)

Dim vegetableB As New Vegetable
vegetableB.Name = "Squash"
vegetableB.Color = "Yellow"
Vegetables.Add(vegetableB)

You then need to add a Clone method to your Vegetable class:

Public Function Clone() As Vegetable
Dim v As New Vegetable
v.Name = Me.Name
v.Color = Me.Color
Return v
End Function
End Sub
End Class

This should fix the problem.

Chris
 
Thanks Chris:
I got your solution to work, but omitted the line:
NewVegetables = New VegetableCollection
my system didn't like this or variations such as
NewVegetables = New Vegetables Collection
Its kind of a moot pt, in that the code is running, but can you clarify on
what this line was intended to do.
thanks
 
I just assumed you had some sort of Collection class so I guessed at
the name 'VegetableCollection'. It was just a guess on my part.
Somewhere you need to create a new 'Vegetables' container using
whatever name is appropriate for your project.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top