foreach循环句柄是否正确更改列表长度?

时间:2015-04-12 04:52:34

标签: c# list foreach iteration

预先正确迭代灵活列表吗?

例如

//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
}

如果确实......怎么样?

4 个答案:

答案 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()将重置枚举。)