The collection was modified by an exception when enumerated in a new subset

I know that changing a collection while enumerating inside it will cause collection was modified exception . But if I get a subcollection from a larger one, and while I list this subcollector, I delete some element from the larger one, I still get this error. Calling ToList in a subset resolves this problem. But why is this happening?

 var localCollection = someData.ToList(); // from DB Context var localGrouped = localCollection.GroupBy(x => x.Id).Select(g => new { Id = g.Key, List = g.Select(x => x.Value) }); or .ToList(); // Here how I solve exception var groups = new List<List<Int64>>(); while (localGrouped.Any()) { var newSelected = new List<Int64>(); var firstGroup = localGrouped.First(); newSelected.Add(firstGroup.Id); localGrouped.Remove(firstGroup); var similiarGroups = localGrouped.Where(x => x.List.Intersect(firstGroup.List).Any()).ToList(); if (similiarGroups.Any()) { foreach (var similiarGroup in similiarGroups) { //Changing something here in parent collection causes exception newSelected.Add(similiarGroup.Id); localGrouped.Remove(similiarGroup); } } groupsOfParcels.Add(newSelected); } 
+2
collections c # exception linq
Apr 30 '14 at 16:50
source share
2 answers

Where not a subset, it is a filter. The difference lies at the heart of how LINQ works.

You can come up with Where , roughly speaking, keeping a reference to the original IEnumerable , as well as some code that checks the condition, and some state that tells how far it went. When you execute getNext() on the Where output, the code snippet passes through the source IEnumerable until it finds an element that satisfies the condition, then returns it (or reaches the end of the original IEnumerable , which means this is also at the end of Where ).

This is a lazy assessment - it considers only as many terms as necessary at any given time. Thus, the original IEnumerable must be present and not be modified in its entirety. If you call ToList() , the evaluation will be carried out immediately - all elements will be extracted and placed in the list before continuing.

The best reading material about this is C # and the god Link, John Skeet. His messages include reimplementing all of Linq’s core functions with a detailed discussion of implementation issues so you can see exactly how they (possibly) work.

Introduction

Part 2 - Where (!)

+6
Apr 30 '14 at 4:55
source share

GroupBy , Where , Select , and most other LINQ operations simply grab IEnumerable from the base collection and repeat it. This underlying IEnumerable throws an exception when it tries to get the next item because the collection has been modified. This exception is thrown by each LINQ statement, because if it cannot get the next element from the base sequence, it will not be able to do its job.

Using ToList , you force the entire sequence to be enumerated before you modify the collection, instead of allowing the enumeration of the base list to be deferred until that list is changed.

+4
Apr 30 '14 at 16:57
source share



All Articles