Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OrderedDictionary breaking change in .NET 4?

Tags:

.net

.net-4.0

A coworker of mine came across this the other day while we were working on upgrading a project to .NET 4.

Given the following code:

 var od = new System.Collections.Specialized.OrderedDictionary();

 od.Add("key1", "value1");
 od.Add("key2", "value2");

 foreach (System.Collections.DictionaryEntry entry in od)
 {
     od[entry.Key] = null;
 }

In .NET 3.5, setting an entry to null will work fine. As expected, the key would still be in the dictionary, and its matching value would be null.

In .NET 4.0, this throws an InvalidOperationException saying

Collection was modified; enumeration operation may not execute.

I thought maybe there was a change to OrderedDictionary where setting an entry to null would remove it entirely, but doing a quick test says the entry is still there when you set it to null.

Is this a breaking change that has gone unreported?

like image 668
rossisdead Avatar asked Mar 01 '11 19:03

rossisdead


3 Answers

From System.Collections.Specialized.OrderedDictionary Class:

The foreach statement is a wrapper around the enumerator, which only allows reading from, not writing to, the collection.

I believe it means that you were using it incorrectly, and it is your fault that you were using it in this way. It wasn't supposed to be working, and it doesn't work now.

like image 82
Snowbear Avatar answered Oct 29 '22 12:10

Snowbear


You have found a breaking change. In previous versions of OrderedDictionary, the internal OrderedDictionaryEnumerator class used array indexes in order to traverse the array. As long as items weren't removed or added, it wouldn't complain.

The new version uses the underlying enumerator that the array itself returns through GetEnumerator, and that's why you're seeing the code fail.

That being said, it's only a breaking change that should never have worked to begin with. It's entirely illegal to modify--in any way--a collection over which you're enumerating, whether it's through a foreach loop or using the IEnumerator explicitly. What you found was a bug that was fixed.

like image 7
Adam Robinson Avatar answered Oct 29 '22 11:10

Adam Robinson


It is a bug fix. The feedback article that triggered the fix is here.

like image 4
Hans Passant Avatar answered Oct 29 '22 13:10

Hans Passant