Zet
Zet

Reputation: 571

List is empty after linq operation

I have problem to understend what is happening in foreach loop- listOfBookedTimes successfuly gets elements that I want, but after execution of the next line listOfBookedTimes is empty. Why? (All lists contain DateTime)

  foreach (var day in allDays)
        {
            list = Rep.GetListOfWorkingHours(fullDayWorkingHours, day, sPWorkingHours);
            bookedTimes = _bookingsService.GetBookedTimes(day, providerId);
            foreach (var b in bookedTimes)
            {
                var listOfBookedTimes = list.Where(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));
                list.RemoveAll(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));
                listOfBookedTimes.Select(m => m.Year - 50);
                list.AddRange(listOfBookedTimes); 
            }

Upvotes: 0

Views: 87

Answers (2)

Alex Art.
Alex Art.

Reputation: 8781

You are removing all elements from the list in this statement

list.RemoveAll(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));

notice that

listOfBookedTimes = list.Where(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));

and

list.RemoveAll(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));

have the same condition

You can execute ToList() in order to get a new copy of the list, so that removing items from the original list won't affect it:

listOfBookedTimes = list.Where(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay)).ToList(); 

BUT

listOfBookedTimes still holds the references to the original items from the list so while adding removing elements to both those lists won't affect each other, modifying properties of single item that is contained by both lists will be applied to both of them.

Upvotes: 3

Toxantron
Toxantron

Reputation: 2398

Your problem is not the RemoveAll but rather the fundemental understanding of LinQ and yield return.

When you call

list.Where(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay));

it is not executed but rather returns an enumerator that will filter the collection on iteration. In the next line you remove all entries you wanted to fetch in the previous line.

When you finally iterate the collection in

list.AddRange(listOfBookedTimes);

it is already empty.

Solution: Add .ToArray() or .ToList() after the Where and it should work as expected. Like this:

var listOfBookedItems = list.Where(m => m.TimeOfDay == (b.TimeOfAppointment.TimeOfDay))
                            .ToList();

Upvotes: 2

Related Questions