Click here to Skip to main content
15,867,568 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
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
VB
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


VB
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
Updated 24-Jan-13 5:20am
v2
Comments
PIEBALDconsult 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 24-Jan-13 18:52pm    
Piebald, what is the correct way then to alter a collection/list through an iteration?

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!
 
Share this answer
 
Comments
Makulais 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 24-Jan-13 11:39am    
What happens when you single step through?
Makulais 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 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 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.
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.
 
Share this answer
 

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