Thanks to Vitaly, I came back and looked again at the code, and it looks like this is a specific implementation decision to prohibit this (see below fragment). The dictionary retains a personal value called verrsion, which increases as the value of an existing element changes. When the enumerator is created, it marks the value at this time, then checks each call on MoveNext.
for (int i = this.buckets[index]; i >= 0; i = this.entries[i].next) { if ((this.entries[i].hashCode == num) && this.comparer.Equals(this.entries[i].key, key)) { if (add) { ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate); } this.entries[i].value = value; this.version++; return; } }
I do not know why this was necessary. You can still change the properties of the value, just do not assign it to the new value:
public class IntWrapper { public IntWrapper(int v) { Value = v; } public int Value { get; set; } } class Program { static void Main(string[] args) { var kvp = new KeyValuePair<string, int>("1",1); kvp.Value = 17; var dictionary = new Dictionary<string, IntWrapper>(){ {"1", new IntWrapper(1)}, {"2", new IntWrapper(2)}, {"3", new IntWrapper(3)} }; foreach (var s in dictionary.Keys) { dictionary[s].Value = 1;
Dolphin Oct 13 '09 at 20:57 2009-10-13 20:57
source share