预先正确迭代灵活列表吗?
例如
//will iterate over all items in list?
foreach (var obj in list)
{
//list length changes here
//ex:
list.Add(...);
list.Remove(...);
list.Concat(...);
// and so on
}
如果确实......怎么样?
答案 0 :(得分:3)
根据documentation,如果在循环内进行了更改,则行为未定义。未定义意味着它可以做什么没有限制,没有"不正确的行为"当行为未定义时...崩溃,做你想做的事,发送电子邮件给你的老板称他讨厌的名字和退出,都同样有效。我希望在这种情况下崩溃,但无论发生什么,都会发生并被认为是正确的#34;根据文件。
答案 1 :(得分:3)
您无法更改同一集合的每个循环内的集合。 如果你愿意,你可以使用for循环来改变收集长度。
答案 2 :(得分:2)
您在foreach循环中使用的集合是immutable。根据{{3}}
foreach语句用于遍历集合以获取 您想要的信息,但不能用于添加或删除 来自源集合的项目,以避免不可预测的副作用。 如果需要在源集合中添加或删除项目,请使用 MSDN循环。
但是根据for,看起来现在可以从.Net 4.0开始了
答案 3 :(得分:2)
在foreach语句中枚举时,无法修改集合。
您应该使用其他模式来执行您尝试执行的操作,因为for each不允许您更改要循环到的枚举器。
例如: 想象一下,如果你从一开始就在一个排序列表上运行foreach,你开始用key =“A”处理项目然后你转到“B”然后你将“C”改为“B”,会发生什么?你的名单已经使用了,你不再知道你在循环什么以及你在哪里。
一般来说,你“可以”用for(int i=dictionary.count-1; i>=0; --i)
或类似的东西来做,但这也取决于你的背景,我真的会尝试使用另一种方法。
内部工作: IEnumerator<t>
旨在启用迭代器模式来迭代元素集合,而不是长度索引。 IEnumerator<t>
包括两名成员。
第一个是bool MoveNext()
。使用此方法,我们可以从集合中的一个元素移动到下一个元素,同时检测我们何时使用布尔返回枚举每个项目。
第二个成员,一个名为Current
的只读属性,返回当前正在处理的元素。通过集合类中的这两个成员,可以使用while循环迭代集合。
此列表中的MoveNext()
方法在超过集合末尾时返回false
。这取代了在循环时计算元素的需要。 (IEnumerator<t>
上的最后一个成员Reset()
将重置枚举。)