在'foreach'循环中修改列表的最佳方法是什么?
在'foreach'循环中修改列表的最佳方法是什么?
C# / .NET 4.0 新特性是你可以在 foreach
中修改可枚举对象而不会出现异常。请参考 Paul Jackson 的博客文章《并发的一个有趣副作用:在枚举时从集合中删除项》来了解这个改变的信息。
以下是如何最好地完成以下操作的方法?
foreach(var item in Enumerable) { foreach(var item2 in item.Enumerable) { item.Add(new item2) } }
通常我会使用 IList
作为缓存/缓冲区,直到 foreach
结束,但是否有更好的方法?
问题的出现原因:
在使用foreach循环遍历列表时,如果在循环体内修改了列表的内容(例如添加新的元素),会导致循环的行为出现问题。这是因为foreach循环在开始时会创建一个列表的副本用于循环,并且不会随着循环体内的修改而更新。因此,当我们在循环体内添加新的元素时,实际上是在修改原始列表而不是副本,这会导致循环的行为不符合预期。
解决方法:
为了在foreach循环中修改列表并保持循环的正确行为,我们可以使用for循环来替代foreach循环。使用for循环时,我们可以手动控制循环的索引,并且在循环体内修改列表的内容不会导致问题。具体的解决方法如下:
var list = new List(); ... // 填充列表 for (int i = 0; i < list.Count; i++) { var entryToProcess = list[i]; var resultOfProcessing = DoStuffToEntry(entryToProcess); if (... condition ...) list.Add(new YourData(...)); }
在上述代码中,我们使用了一个for循环来遍历列表,并且手动控制了循环的索引。在每次循环中,我们获取当前索引对应的列表元素进行处理,并根据条件判断是否添加新的元素到列表中。这样做可以确保在循环体内对列表的修改是安全的,不会导致循环行为的问题。
下面是一个可运行的示例代码,演示了使用for循环修改列表的情况:
void Main() { var list = new List(); for (int i = 0; i < 10; i++) list.Add(i); for (int i = 0; i < list.Count; i++) { var entry = list[i]; if (entry % 2 == 0) list.Add(entry + 1); Console.Write(entry + ", "); } Console.Write(list); }
上述示例代码中,我们创建了一个包含0到9的整数列表。然后,我们使用for循环遍历列表,并在循环体内判断每个元素是否为偶数,如果是则添加其加一的结果到列表中。最后,我们输出循环过程中遍历到的元素以及最终的列表内容。
该示例的输出结果如下:
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 3, 5, 7, 9, List (15 items) 0 1 2 3 4 5 6 7 8 9 1 3 5 7 9
可以看到,循环过程中遍历到了修改后的列表内容,并且最终的列表包含了所有添加的新元素。这证明了使用for循环可以在循环体内修改列表并保持正确的循环行为。