OrderedDictionary breaking change in .NET 4?
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 t开发者_C百科hat has gone unreported?
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.
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.
It is a bug fix. The feedback article that triggered the fix is here.
The error has nothing to do with null. It has everything to do with the fact that you are modifying the collection in a foreach
loop. Doing so invalidates the iterator and breaks the enumeration process.
You can safely set the value to null (for nullable value types, that is), outside of the foreach.
That is, this will work:
od.Add("key2", null);
精彩评论