如何在在遍历通用列表时从中移除元素?
如何在在遍历通用列表时从中移除元素?
我正在寻找一个更好的模式来处理一个元素列表,每个元素都需要处理,然后根据结果从列表中删除。
你不能在foreach (var element in X)
中使用.Remove(element)
(因为它会导致Collection was modified; enumeration operation may not execute.
异常)
你也不能使用for (int i = 0; i < elements.Count(); i++)
和.RemoveAt(i)
,因为它会打乱你在集合中的当前位置相对于i
的位置。
有没有更优雅地处理这个问题的方法?
admin 更改状态以发布 2023年5月23日
foreach (var item in list.ToList()) { list.Remove(item); }
如果你在列表(或LINQ查询结果)中添加".ToList()",你可以直接从"list"中删除"item",而不会出现可怕的“Collection was modified; enumeration operation may not execute.” 错误。编译器会复制"list",以便您可以安全地在数组上执行删除。
虽然这种模式不是超级有效的,但它具有自然的感觉,并且足够灵活以适应几乎任何情况。例如,当你想把每个"item"保存到数据库时,只有在数据库保存成功后才将其从列表中删除。
使用for循环反向迭代你的列表:
for (int i = safePendingList.Count - 1; i >= 0; i--) { // some code // safePendingList.RemoveAt(i); }
示例:
var list = new List(Enumerable.Range(1, 10)); for (int i = list.Count - 1; i >= 0; i--) { if (list[i] > 5) list.RemoveAt(i); } list.ForEach(i => Console.WriteLine(i));
或者,你可以使用RemoveAll方法和一个谓词来测试:
safePendingList.RemoveAll(item => item.Value == someValue);
这是一个简化示例来演示:
var list = new List(Enumerable.Range(1, 10)); Console.WriteLine("Before:"); list.ForEach(i => Console.WriteLine(i)); list.RemoveAll(i => i > 5); Console.WriteLine("After:"); list.ForEach(i => Console.WriteLine(i));