在休息之前在foreach中删除

时间:2013-02-27 08:40:06

标签: c# foreach

我知道有很多方法可以做得更好但我已经在现有代码中看到了它,现在我想知道这是否会产生任何负面影响。请注意删除后的休息时间。因此,我一般不关心迭代器,但是,我确实关心意外行为( - >潜在的异常)。

foreach (var item in items)
{
    //do stuff
    if (item.IsSomething)
    {
        items.Remove(item); //is this safe???
        break;
    }
}

编译器是否也可以以我不期望的方式优化某些内容?

4 个答案:

答案 0 :(得分:7)

编译器在Dispose()块中执行的枚举器上生成对finally的调用,但这应该不是问题。如果您在删除项目后立即break,则不会发生任何错误,因为您不再使用枚举器。

如果你想以不同的方式(出于样式或其他原因),你可以这样做:

var item = items.FirstOrDefault(i => i.IsSomething);
if (item != null) {
    items.Remove(item);
}

它也有点短:)(我假设你在这里使用你的集合中的引用或可空类型。)

答案 1 :(得分:2)

编译器和与您的应用程序保持联系的所有其他内容保证了SC-DRF(无数据竞争程序的顺序一致性),因此您不会看到您编写的程序与执行的程序之间的区别(这不过是一样的)。假设在多个线程之间没有共享items,那么写入是完全安全的,除了在循环外调用Remove之外没有其他意外行为。

答案 2 :(得分:1)

在foreach中迭代时无法更改列表。

在枚举时,无法修改基础集合。标准方法是在第二个列表中保留要删除的项目,然后在枚举项目之后,从项目中删除每个项目。

答案 3 :(得分:-1)

那么你可以这样做 - 在处理大型列表时更有效率(假设实体框架)

var reducedList = items.where(a=>a.IsSomething).toList();
foreach(var item in reducedList)
{
    reducedList.Remove(item);
}

这减少了foreach循环迭代