Vit*_*liy 26 c# dictionary enumeration invalidoperationexception
class Program
{
static void Main(string[] args)
{
var dictionary = new Dictionary<string, int>()
{
{"1", 1}, {"2", 2}, {"3", 3}
};
foreach (var s in dictionary.Keys)
{
// Throws the "Collection was modified exception..." on the next iteration
// What's up with that?
dictionary[s] = 1;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我完全理解为什么在枚举列表时抛出此异常 - 在枚举期间,枚举对象的结构不会改变似乎是合理的.但是,更改字典的值会改变其结构吗?具体来说,其键的结构?
Jar*_*Par 19
因为值和键存储为一对.键和值没有单独的结构,而是单个结构,它将两者都存储为一对配对值.更改值时,必须更改包含键和值的单个基础结构.
更改值是否必然会改变基础结构的顺序?不是.但这是一个特定于实现的细节Dictionary<TKey,TValue>,正确地认为类是通过允许修改值作为API的一部分来揭示这一点.
实际上,我看到你来自哪里.这里没有注意到的大多数答案是你在Keys列表中迭代,而不是字典的项目本身.如果.NET框架程序员想要,他们可以相当容易地区分对字典结构所做的更改以及对字典中的值所做的更改.然而,即使人们遍历集合的密钥,他们通常也会最终获得价值.我怀疑.NET框架设计师认为,如果你在迭代这些值,你会想知道是否有什么东西正在改变它们,就像任何List一样.无论是那个还是他们都认为这不是一个重要的问题,值得进行编程和维护,以区分一种变化和另一种变化.
感谢Vitaliy,我回过头来看了一下代码,看起来它是一个特定的实现决定,不允许这样做(参见下面的代码片段).字典保留一个名为verrsion的私有值,在更改现有项的值时会增加该值.创建枚举数时,它会记下当时的值,然后检查每次调用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;
}
}
Run Code Online (Sandbox Code Playgroud)
我不知道为什么这是必要的.您仍然可以自由修改值的属性,只是不将其分配给新值:
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; //OK
dictionary[s] = new IntWrapper(1); // boom
}
}
}
Run Code Online (Sandbox Code Playgroud)
Indexer onDictionary可能是一种可以更改集合结构的操作,因为如果该键不存在,它将添加一个具有此类键的新条目。这显然不是这里的情况,但我希望Dictionary契约故意保持简单,因为对象上的所有操作都分为“变异”和“非变异”,并且所有“变异”操作都使枚举器无效,即使它们实际上不要改变任何东西。
| 归档时间: |
|
| 查看次数: |
9572 次 |
| 最近记录: |