.NET Framework Bookmark and Share   
 index > .NET Base Class Library > Exception While Using Enumerable.Where Method In Dictionary
 

Exception While Using Enumerable.Where Method In Dictionary

I'm getting a collection of KeyValuePairs by using the Enumerable.Where method with a dictionary. After I get the collection I try to iterate through the collection of keys to remove the keys I found using the where method from the dictionary but am getting a 'Collection was modified; enumeration operation may not execute.' exception when I try to modify the dictionary.

I'm confused about why this is happening, since I'm not actually iterating through the dictionary anymore!

fileDict is a dictionary(of string, string) containing a list of files. The code block works fine if I remove the lines which modify the dictionary.

I'm guessing that the Enumerable.Where method continues to run even though it's already returned values? I hope someone can explain!

                Dim oldKeys As IEnumerable(Of KeyValuePair(Of String, String)) = fileDict.Where(Function(grepDict) Regex.Match(grepDict.Key, fixPath(e.OldFullPath)).Success)

                Console.WriteLine("oldkeys count " & oldKeys.Count)

                For Each s As KeyValuePair(Of String, String) In oldKeys
                    Console.WriteLine("oldkey " & s.Key & "," & s.Value)
                    tempStr = s.Value
                    fileDict.Remove(s.Key)
                    fileDict.Add(fixPath(e.FullPath), Regex.Replace(tempStr, fixPath(e.OldFullPath), fixPath(e.FullPath)))
                Next

                Dim newKeys As IEnumerable(Of KeyValuePair(Of String, String)) = fileDict.Where(Function(grepDict) Regex.Match(grepDict.Key, fixPath(e.FullPath)).Success)

                For Each s As KeyValuePair(Of String, String) In newKeys
                    Console.WriteLine(s.Key & "," & s.Value)
                Next

three_sixteen

LINQ extension methods are lazy loading. This means that the with each iteration of the result of the LINQ method, the LINQ method looks up the next value from the original source. In other words, it doesn't get all the values at once, instead, it fetches the values as you use them. When it's looking up it's values from the original source, and you change the source, you get this error.

I hope that makes sense.

In any case, you can fix this by calling .ToList() on the IEnumerable.

Dim oldKeys As IEnumerable(Of KeyValuePair(Of String, String)) = fileDict.Where(Function(grepDict) Regex.Match(grepDict.Key, fixPath(e.OldFullPath)).Success).ToList()

This forces the evaluation, and puts the IEnumerable<T> into a situation where it's not dependent on the original data.


Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki �LinkedIn �ForumsBrowser
David M Morton

LINQ extension methods are lazy loading. This means that the with each iteration of the result of the LINQ method, the LINQ method looks up the next value from the original source. In other words, it doesn't get all the values at once, instead, it fetches the values as you use them. When it's looking up it's values from the original source, and you change the source, you get this error.

I hope that makes sense.

In any case, you can fix this by calling .ToList() on the IEnumerable.

Dim oldKeys As IEnumerable(Of KeyValuePair(Of String, String)) = fileDict.Where(Function(grepDict) Regex.Match(grepDict.Key, fixPath(e.OldFullPath)).Success).ToList()

This forces the evaluation, and puts the IEnumerable<T> into a situation where it's not dependent on the original data.


Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki �LinkedIn �ForumsBrowser
David M Morton
I'm pretty sure that did the trick, though now my code isn't behaving how I would like it. I'll have to play around with it a bit and try to figure it out. Out of curiosity, would best practice dictate that I cast it to a dictionary instead of a list?

How am I able to iterate through the list while using keyvaluepairs?
three_sixteen

I believe there's a "ToDictionary()" method where you have an IEnumerable<KeyValuePair<TKey, TValue>>. You could use that.


Coding Light - Illuminated Ideas and Algorithms in Software
Coding Light Wiki �LinkedIn �ForumsBrowser
David M Morton
Bah, can't seem to figure it out - I barely just figured out how to use the where method :) Thanks for your help David!
three_sixteen

You can use google to search for other answers

Custom Search

More Threads

• any api for a sidebar? just like vista sidebar
• How do I pass Binary data to an unmanaged C++ func from C#?
• Invalid class string while executing crystal report.
• Public key generated with OpenSSL - How can I use it.
• Windows Service and System.Drawing Namespace
• Given a path to an application, how do I extract the application's name?
• Memory usage increasing with every navigation | WebBrowser Component | VB.NET
• String Methods , how to convert a Capitalized string in to A name ?
• Win32 Device Paths and FileStream
• ASP.Net control to edit HTML document