Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: VB.NET
I have come across this issue multiple times, and I'm sure it has something to do with my lack of understanding. If someone would be kind enough to explain the problem and why it doesn't do what I expect, and how to properly frame the code, I would greatly appreciate it. I cut out sections but you should be able to understand what I'm doing.
 
I have a ForEach loop nested inside another ForEach loop, the inside nest, although it appears to successfully iterate through the object, won't update it? I use watches, breakpoints, ... it all shows fine, the variable time is updating correctly and has the correct value. The current_pvt is correct, the current_move is correct, but after the call
current_pvt.time = time
I check the current_pvt.time value and it's the same as it was previous to the assignment or the same as the current_pvt.time value for the previous current_move? I can't tell for sure as they are the same prior to the statement. Memory serves from earlier attempts on different code that is writes it with the first current_move value.
 
What gives? I have seen this while writing this nested ForEach so apparently I am doing something fundamentally wrong. Typically the first time through the inner loop it updates correctly, but the following times, it does not, so I assume it has to do with the object not be updated, destroyed, renewed properly? How should I write a nested ForEach Loop like this with two different objects?
 
Thank you,
 
Kennard
 

Public Class _program
    Public programname As String
    Public moves As List(Of _move)
 
    Public Sub New()
        progglobals = New _globals
        moves = New List(Of _move)
    End Sub
 
End Class
 
Public Structure PVT
    Public X As Double
    Public Y As Double
    Public Xvel As Double
    Public Yvel As Double
    Public time As Double
End Structure
 
Public Class _move
    Public moveID As Integer
    Public pvtPts As New List(Of PVT)
    Public timeslice As Double
End Class
 
 Private Sub SetPVTTimes(ByRef current_program As Prog._program)
        Dim time As Double = 0.0
 
        For Each current_move As Prog._move In current_program.moves
            If current_move.pvtPts.Count = 0 Then
               time = 0.0
            Else
                For Each current_pvt As Prog.PVT In current_move.pvtPts
                    current_pvt.time = time
                    time = time + current_move.timeslice
                Next
            End If
        Next
    End Sub
 
Posted 24-Jan-13 4:55am
Edited 24-Jan-13 5:20am
v2
Comments
PIEBALDconsult at 24-Jan-13 11:35am
   
Not having read your code, I must ask whether or not you're trying to alter a collection while you foreach it; such is not allowed.
Makulais at 24-Jan-13 18:52pm
   
Piebald, what is the correct way then to alter a collection/list through an iteration?
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

I think you need to look at this a bit more closely - I suspect that the problem is more likely to be that you haven't compiled the code.
Specifically, the code you show won't compile, because "timeslice" is not a member of the _move class.
 
Either your code as shown has some (possibly important) bits missing, or it hasn't been compiled, and you are trying to find a bug in your code, that isn't in there!
 
Try putting a breakpoint just before the outer loop and single stepping through - I bet the debugger complains that the code doesn't match the source!
  Permalink  
Comments
Member 8462201 at 24-Jan-13 11:19am
   
As I said, I cut alot out when i copied it, I must have cut timeslice out of the move class. just put it back it as a double. There are no compiler errors in the code I am running.
OriginalGriff at 24-Jan-13 11:39am
   
What happens when you single step through?
Makulais at 24-Jan-13 11:49am
   
the value of current_pvt.time is updated during the step, but if i go to the current_program.moves and expand it out, the value is not updated there. I have the output also written to a csv and it's not updating. there is some kind of disconnect between the current_pvt and the current_program variables? Like i am updating a copy of the current_pvt and not the actual variable in the current_program object.
Makulais at 24-Jan-13 11:56am
   
the value of current_pvt.time is updated during the step, but if i go to the current_program.moves and expand it out, the value is not updated there. I have the output also written to a csv and it's not updating. there is some kind of disconnect between the current_pvt and the current_program variables? Like i am updating a copy of the current_pvt and not the actual variable in the current_program object. I also look at the current_move, expand it out, and the pvtPts object is not updated there.
OriginalGriff at 24-Jan-13 14:14pm
   
I just converted your code to C# (I'm a lot more comfortable with C# for complicated stuff) and it becomes pretty obvious - you even get a compilation error.
The problem is pretty simple - you can't change current_pvt or any of it's variables within a for each loop - because it is the target of an iterator and changing them is not allowed. Why you don't get an error in VB I don't know, but in C# you do - and quite correctly. I think what happens with the vb is that a copy of curent_pvt is constructed, and modified within the loop, then discarded at the end.
Try changing it to a for loop (which doesn't use an iterator) and you problem will probably magically disappear.
Makulais at 24-Jan-13 18:46pm
   
OriginalGriff, your thought is what I was seeing and what i was theorizing, but it works on the outer loop? Strange. I can't use a for loop unless i convert it to an array because i get the syntax error "Expression is a value and therefore cannot be the target of an assignment." unless i'm writing that code wrong?
 
For i As Integer = 0 To current_move.pvtPts.Count - 1
current_move.pvtPts(i).time = time + current_move.timeslice
Next
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

Ah, found the reason and solution over on another site.
 
Prog.PVT is a structure, when you work with a structure, since it is a value type, I get a copy of it, not the original. I need to change it to a Class in order to iterate and change the items. If not, then the method I posted above would work since it creates a new item for the list and replaces the old one with it.
  Permalink  

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

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 518
1 OriginalGriff 459
2 ChintanShukla 305
3 Richard Deeming 275
4 RyanDev 230
0 Sergey Alexandrovich Kryukov 8,858
1 OriginalGriff 7,451
2 CPallini 2,603
3 Richard MacCutchan 2,095
4 Abhinav S 1,893


Advertise | Privacy | Mobile
Web02 | 2.8.140827.1 | Last Updated 24 Jan 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100