我知道有很多方法可以做得更好但我已经在现有代码中看到了它,现在我想知道这是否会产生任何负面影响。请注意删除后的休息时间。因此,我一般不关心迭代器,但是,我确实关心意外行为( - >潜在的异常)。
foreach (var item in items)
{
//do stuff
if (item.IsSomething)
{
items.Remove(item); //is this safe???
break;
}
}
编译器是否也可以以我不期望的方式优化某些内容?
答案 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
循环迭代