It’s a bug you’ve probably learned to avoid in .NET programming, it’s just not as obvious now.
var cities = new List<string> { "Baltimore", "Munich", "Copenhagen" }; var citiesToRemove = cities.Where(city => city.Length < 7); foreach (var s in citiesToRemove) { cities.Remove(s); }What goes wrong, and what’s an easy fix?
--
All links to my “What’s Wrong” series are here.
Comments
citiesToRemove is being lazily evaluated in the foreach, and thus has an enumerator for cities open. The easy fix is to call .ToList() after the call to .Where() when initializing citiesToRemove.
msdn.microsoft.com/en-us/library/ttw7t8t6.aspx
cities.RemoveAll(c => c.Length < 7);
I remembered that "Effective C#" discussed this topic.
foreach (var s in citiesToRemove.ToList())
I think it's tricky because it looks like citiesToRemove is a different collection...
The List's RemoveAll takes a predicate and would make a fix that would also take a lot less code.
Sorry I didn't call that out earlier!
{
cities.Remove(s);
}
By converting it to an array or any other IEnumerable before removing an element this issue is resolved.