可能重复:
How to modify or delete items from an enumerable collection while iterating through it in C#
听着,我不想知道基本的foreach。我在谈论控制这个错误的那个:
"The enumerator is not valid because the collection changed."
当我这样做时会发生这种情况:
foreach(Image image in images)
{
if(...)
{
images.remove(image)
}
}
我相信有一个特殊的迭代器可以很好地处理这个问题,就像Java一样。 那么,我怎么能在C#中做到这一点呢? 谢谢!
答案 0 :(得分:5)
或者只是删除它而不需要手动迭代:
images.RemoveAll(image=>...)
适用于List<T>
但许多其他容器不支持它。
处理IList<T>
的O(n)解决方案:
void RemoveWhere(this IList<T> list,Predicate<T> pred)
{
int targetIndex=0;
for(int srcIndex=0;srcIndex<list.Count;srcIndex++)
{
if(pred(list[srcIndex]))
{
list[targetIndex]=list[srcIndex];
targetIndex++;
}
for(int i=list.Count-1;i>=targetIndex;i--)
list.RemoveAt(i);
}
}
在你点击第一个删除的项目之前,可以通过不分配加快一点。
答案 1 :(得分:4)
for (var i = 0; i < images.Count; ++i)
{
if (...)
{
images.RemoveAt(i);
--i;
}
}
答案 2 :(得分:2)
你不能用C#。
您可以做的是收集要删除的对象,然后将其删除:
Image[] imagesToRemove = images.Where(image => ...).ToArray();
foreach (Image image in imagesToRemove)
images.remove(image);
答案 3 :(得分:1)
肯特的答案将有效,因为它实现了IList<T>
。对于没有的东西,你必须建立一个你想要删除的东西的列表。例如:
public static void RemoveWhere<T>(this ICollection<T> self, Func<T, bool> predicate)
{
var toRemove = self.Where(predicate).ToList();
foreach (var i in toRemove)
self.Remove(i);
}