By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
459,462 Members | 1,126 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 459,462 IT Pros & Developers. It's quick & easy.

Adding items to a List(of object

!NoItAll
100+
P: 296
I have some code that adds items to a List(of Object). It is behaving extremely bizarre!

Here's my original code
Expand|Select|Wrap|Line Numbers
  1. Dim BeaconStoryList as New List(Of My.StoryType)
  2. Dim BeaconStory as New My.StoryType
  3. Dim NewStories() as New Foriegn.StoryType = GetStories
  4.  
  5. For Each Story as Foriegn.StoryType in NewStories
  6.      If Story.Type = My.BeaconType then
  7.          BeaconStory.Title = Story.storyTitle
  8.          BeaconStory.Body = Story.storyBody
  9.          BeaconStory.Type = Story.storyType
  10.          BeaconStoryList.Add(BeaconStory)
  11.     End if
  12. Next
  13.  
This seamed pretty straight forward to me. There might be 20 stories, 5 of which were of type "My.BeaconType" and after the for each loop I would have a list(of collection of those 5 stories assigned to BeaconStoryList.
But...
After completing the loop every element in the collection would get the exact same values. Even though all 5 stories were different, all elements in the collection would get assigned the last values added to the end.
To stop this bizarre behavior I had to change the code to this
Expand|Select|Wrap|Line Numbers
  1. Dim BeaconStoryList as New List(Of My.StoryType)
  2. Dim NewStories() as New Foriegn.StoryType = GetStories
  3. Dim I as Integer = 0
  4.  
  5. For Each Story as Foriegn.StoryType in NewStories
  6.      If Story.Type = My.BeaconType then
  7.          BeaconStoryList.Add(New My.StoryType)
  8.          BeaconStoryList(I).Title = Story.storyTitle
  9.          BeaconStoryList(I).Body = Story.storyBody
  10.          BeaconStoryList(I).Type = Story.storyType
  11.          I +=1
  12.     End if
  13. Next
  14.  
There must be something I do not understand that is going on. In the first code example I could step through the code with watch-points and actually see all of the indexes (0 through the current one) change value. For example: If I was on the first loop the BeaconStory.Title might be "Gravy". Then passing through the second loop the next story title would be "Chicken" so I would assume that BeaconStoryList(0).Title would be "Gravy" and BeaconStoryList(1).Title would be "Chicken".
But as soon as the code assigned "Chicken" to BeaconStory.Title, then BeaconStoryList(0).Title would also change to "Chicken".
With my second version of the code this did not happen.
It's as though it was placing pointers into the elements of the array rather than values. If that is the case, however, then why does my second version of the code work - I'm still passing in the same thing - aren't I?

!NoItAll
Mar 28 '10 #1
Share this Question
Share on Google+
3 Replies


tlhintoq
Expert 2.5K+
P: 3,525
In your Story class, are each of these properties set to static? If they are, then that is why you get the same values back.
Mar 28 '10 #2

!NoItAll
100+
P: 296
Ok - figured it out. Again - my own lack of experience surfaces like a bloated body in a lake...
ewwww!
My problem is that I did not understand how to properly create an array of my class. It's not as simple as:

Dim MyClassArray(20) as MyClass

Nor is it as easy as

Dim MyClassArray() as MyClass
Redim MyClassArray(20)

At this point you do have 20 elements of the MyClass type, but there is nothing in them. Look at it in the debugger and you will see none of the individual elements from the MyClass appear. The next step is to fill in the elements of the class into each element of the array:

For I = 0 to 20
MyClassArray(I) = new MyClass
Next I


So that was PART of my problem. The other part of my problem is that the loop:

Expand|Select|Wrap|Line Numbers
  1.  
  2. For Each Story as Foriegn.StoryType in NewStories
  3.       If Story.Type = My.BeaconType then
  4.           BeaconStory.Title = Story.storyTitle
  5.           BeaconStory.Body = Story.storyBody
  6.           BeaconStory.Type = Story.storyType
  7.           BeaconStoryList.Add(BeaconStory)
  8.      End if
  9.  Next
  10.  
Was actually just putting a pointer from each BeaconStory into the BeaconStoryList. Whenever I assigned a new value to any of the elements in BeaconStory then ALL elements inside of the BeaconStoryList would match.

To fix this all I needed to do was add one line of code within the loop

BeaconStory = New My.Storytype

So the code looks like this now:
Expand|Select|Wrap|Line Numbers
  1.  
  2. For Each Story as Foriegn.StoryType in NewStories
  3.       If Story.Type = My.BeaconType then
  4.           BeaconStory = New My.StoryType
  5.           BeaconStory.Title = Story.storyTitle
  6.           BeaconStory.Body = Story.storyBody
  7.           BeaconStory.Type = Story.storyType
  8.           BeaconStoryList.Add(BeaconStory)
  9.      End if
  10.  Next
  11.  
The addition of BeaconStory = New My.StoryType created a new copy of Beaconstory so that unique elements were created for addition into the BeaconStoryList.

This seemed confusing to me at first - but it appears that with created classes all you are ever passing in and out are pointers to the values (byRef) and not the actual data.

Still learning...
Mar 28 '10 #3

!NoItAll
100+
P: 296
Interesting tlhintoq - I don't specifically create anything as Static - I don't even know how to do that... Is it a default?

Here's an example of one of my classes

Expand|Select|Wrap|Line Numbers
  1. Public Class Story_type
  2.     Private vBody As String
  3.     Private vTitle As String
  4.     Private vType As Integer = 0
  5.  
  6.     Public Property Body() As String
  7.         Get
  8.             Return vBody
  9.         End Get
  10.         Set(ByVal value As String)
  11.             vBody = value
  12.         End Set
  13.     End Property
  14.  
  15.     Public Property Title() As String
  16.         Get
  17.             Return vTitle
  18.         End Get
  19.         Set(ByVal value As String)
  20.             vTitle = value
  21.         End Set
  22.     End Property
  23.  
  24.     Public Property Type() As Integer
  25.         Get
  26.             Return vType
  27.         End Get
  28.         Set(ByVal value As Integer)
  29.             vType = value
  30.         End Set
  31.     End Property
  32.  
  33. End Class
  34.  
And then to set up the List(of I do this:

Expand|Select|Wrap|Line Numbers
  1. Public Class ArrayOfStory_type
  2.     Inherits List(Of Story_type)
  3. End Class
  4.  
Is this cool - or weird?
Mar 28 '10 #4

Post your reply

Sign in to post your reply or Sign up for a free account.