San*_*eep 4 .net c# collections
这个问题很多时候都在这个论坛上被问到.我知道问题的解决方案.但我很想知道为什么"修改集合时无法执行枚举操作"
List<string> list = new List<string>();
list.Add("a");
list.Add("b");
int[] array = new int[6] { 1, 2, 3, 4, 5, 5 };
HashSet<int> hashSet = new HashSet<int>();
int i = 0;
foreach (string s in list)
{
list[i] = "test";
i++;
}
Run Code Online (Sandbox Code Playgroud)
但是当我将列表更改为list.toarray有效时.
通常,.Net集合不支持同时枚举和修改.当您处于枚举它的中间时,该行list[i] = "test"会修改集合list,因此会生成异常.确实,这是一个微不足道的修改,不会影响列表的结构,但List<T>即使将修改视为具有破坏性.
该ToArray版本有效,因为现在您有2个集合
list你实际上然后枚举数组,因此修改原始list就好了.
Microsoft指定修改该对象时,任何实现iEnumerable的对象都必须使所有现有枚举无效。此要求的一般原因是,对于许多类型的集合,很难确保在修改集合时枚举器将表现出合理的行为。例如,假设一个List包含五个值(A,B,C,D,E),并且一个枚举数通过将n设置为元素数来工作,然后输出element(0),element(1)等。元素(n-1)。如果在枚举器枚举element(2)[C]时,元素BB插入元素(1)[即B]之后,则枚举器可能会继续输出元素(3)[再次为C],然后元素4 [D],然后决定完成,因为它输出了所有五个元素。那将是一个糟糕的情况(一个要素出现两次,而一个要素丢失)。
如果对集合进行某种修改以防止枚举器产生有意义的结果,则使枚举器无效应该是合理的。但是,在我看来,即使集合经过修改,但能够满足以下合同的枚举数也应这样做,而不是抛出异常:
VB6样式的集合似乎符合上述语义,但其他标准集合都没有。太糟糕了-某些数据结构可以很好地满足这些要求,但足以避免重复存储列表数据,这在当前规则下经常是必需的。