necrofish666 necrofish666 - 1 year ago 84
C# Question

C# foreach statement not adding models to model list correctly

I have two foreach loops, which are building a timeline of events in my application. I have a timeline list object, which is a list of timeline details objects. The code looks like this:

var viewModel = new TimeLineListViewModel();
var timelineDetailsViewModel = new TimelineDetailsViewModel();

var referralDiaryEvents = _referralService.GetReferralDiaryEventsByReferralId((int)referralId).ToList();

var referral = _referralService.GetReferral((int)referralId);

foreach (var referralDiaryEvent in referralDiaryEvents)
1 timelineDetailsViewModel.EventDate = referralDiaryEvent.App_DiaryEvent.EventDateTimeScheduled;
2 timelineDetailsViewModel.EventType = referralDiaryEvent.App_DiaryEvent.Ref_EventType.Description;
3 timelineDetailsViewModel.EventDescription = referralDiaryEvent.App_DiaryEvent.EventName;

4 viewModel.TimeLineList.Add(timelineDetailsViewModel);

foreach (var referralStatusHistory in referral.App_ReferralStatusHistory)
timelineDetailsViewModel.EventDate = referralStatusHistory.DateChanged;
timelineDetailsViewModel.EventType = "Referral Status Changed: " + referralStatusHistory.Ref_ReferralStatus.Description;
timelineDetailsViewModel.EventDescription = referralStatusHistory.Ref_ReferralStatusReason.Description;


This all should be straightforward, and should be adding each item in each of the loops to build up a list of objects. The problem is that it's not doing that. I actually have no idea what it's doing - when I debug and run through the loop, it's doing some really weird stuff. I've numbered the lines of code in the loop for reference. It'll run through line 1, then run through line 2, then back to line 1, then onto line 3, then back to line 2, then onto line 4, and so on, it jumps back and forth through the loop for no apparent reason instead of running straight through the loop, line after line.

Then eventually it will add the timelineDetailsViewModel to the TimeLineList. Then it'll start the loop again for the next item, but when it gets to adding the timelineDetailsViewModel to the TimeLineList again, the TimeLineList count becomes 0, then jumps back to line 2, then back to 4 again, then adds the item to the list, but overwrites every item that was previously added to the list to that all of the timelineDetailsViewModel items in the list are the same as the latest added item. So by the time it gets to the bottom of the 2nd foreach loop, in my code there should be seven unique timelineDetailsViewModel items in the list, all with different details - there does end up being seven items, but they are all the same as the last timelineDetailsViewModel that was added during the last loop of the 2nd foreach loop.

Does anybody have any idea what's happening here? Is my visual studio broken? I've tried a restart on my machine but to no avail. I'm using visual studio 2012.

Answer Source

It does not explain the weird debugger behaviour, but you actually have another bug in your code:

You are creating the instance of TimeLineListViewModel and TimelineDetailsViewModel only once. Then, iterating through the foreach loops, you always change the properties of exactly the same instance.

In each run through the loops you are changing the properties of the only instance you ever created and try to add this very instance x times to your lists.

You need to create the instances inside your foreach loops:

foreach (var referralDiaryEvent in referralDiaryEvents)
    // create a NEW instance for every event!
    var timelineDetailsViewModel = new TimelineDetailsViewModel();

    timelineDetailsViewModel.EventDate = referralDiaryEvent.App_DiaryEvent.EventDateTimeScheduled;
    timelineDetailsViewModel.EventType = referralDiaryEvent.App_DiaryEvent.Ref_EventType.Description;
    timelineDetailsViewModel.EventDescription = referralDiaryEvent.App_DiaryEvent.EventName;

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download