Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying .NET Dictionary while Enumerating through it

Tags:

c#

.net

I'm using a Dictionary<long, bool> and I want to change it while I enumerate through it, but it seems this is not allowed. How can I do this?

like image 217
Dimitar Vouldjeff Avatar asked Feb 27 '10 12:02

Dimitar Vouldjeff


5 Answers

Don't, basically. It's explicitly not supported. From the docs for Dictionary<,>.GetEnumerator():

An enumerator remains valid as long as the collection remains unchanged. If changes are made to the collection, such as adding, modifying, or deleting elements, the enumerator is irrecoverably invalidated and its behavior is undefined.

Typically the best way is to remember the modifications you want to make, and then perform them afterwards. Or you could take a copy of the dictionary to start with and then iterate through that while you modify the original. If you could give us more information about what you're trying to do, that would help.

Having said this, the new ConcurrentDictionary class in .NET 4.0 does permit this - but the results of the iteration aren't guaranteed - you may see the changes while you're iterating, or you may not.

like image 109
Jon Skeet Avatar answered Oct 22 '22 06:10

Jon Skeet


You should store the key or object you want to delete and break the loop, and then use the Remove() method to delete the object from the dictionary.

like image 22
Prashant Lakhlani Avatar answered Oct 22 '22 08:10

Prashant Lakhlani


Ideally, it is not advisable to do it. The GetEnumerator() that is called while iterating to the next item will throw an InvalidOperationException. However, from .netcore 3.1 onwards, this will work when you do a dictionary.Remove() or dictionary.Clear() from inside the loop.

Here is the documentation.

like image 5
Auro Avatar answered Oct 22 '22 08:10

Auro


As of .net core 3 and higher, this is now possible to Remove items from the dictionary, without invalidating the enumerator (foreach loop):

From the docs here:

.NET Core 3.0+ only: The only mutating methods which do not invalidate enumerators are Remove and Clear.

You should be able to loop through, and remove elements, without causing an error. Creating a list or array as a workaround is no longer needed.

like image 2
ugh StackExchange Avatar answered Oct 22 '22 07:10

ugh StackExchange


I answered it here with respect to queue's but the answer is the same. You can't enumerate with foreach and modify the collection at the same time.

like image 1
Jason Punyon Avatar answered Oct 22 '22 08:10

Jason Punyon