你可以在C#中迭代它时从List 中删除一个项目吗?

您可以在迭代它时从列表中删除项目吗? 这会有用,还是有更好的方法呢?

我的代码:

foreach (var bullet in bullets) { if (bullet.Offscreen()) { bullets.Remove(bullet); } } 

-edit-对不起,伙计们,这是一个silverlight的游戏。 我没有意识到Silverlight与Compact Framework不同。

编辑 :澄清一下,问题是关于Silverlight ,它显然不支持List`T上的RemoveAll 。 它在完整的框架,CF,XNA版本2.0+中可用

您可以编写一个表示删除条件的lambda:

 bullets.RemoveAll(bullet => bullet.Offscreen()); 

或者你可以选择你想要的那些,而不是删除你不想要的那些:

 bullets = bullets.Where(b => !b.OffScreen()).ToList(); 

或者使用索引器向后移动序列:

 for(int i=bullets.Count-1;i>=0;i--) { if(bullets[i].OffScreen()) { bullets.RemoveAt(i); } } 
 bullets.RemoveAll(bullet => bullet.Offscreen()); 

编辑:要使此工作在Silverlight中按原样运行,请将以下扩展方法添加到项目中。

List.RemoveAll ,此算法为O(N),其中N是列表的长度,而不是O(N * M),其中M是从列表中删除的元素的数量。 因为它是一个扩展方法,与非Silverlight框架中的RemoveAll方法具有相同的原型,所以内置的一个将在可用时使用,并且这个无缝地用于silverlight构建。

 public static class ListExtensions { public static int RemoveAll(this List list, Predicate match) { if (list == null) throw new NullReferenceException(); if (match == null) throw new ArgumentNullException("match"); int i = 0; int j = 0; for (i = 0; i < list.Count; i++) { if (!match(list[i])) { if (i != j) list[j] = list[i]; j++; } } int removed = i - j; if (removed > 0) list.RemoveRange(list.Count - removed, removed); return removed; } } 

试图在foreach循环中删除它会引发exception。 您需要使用for循环向后迭代它。

 for (int count = bullets.Count - 1; count >= 0; count--) { if (bullets[count].Offscreen()) { //bullets.Remove(bullets[count]); bullets.RemoveAt(count); } } 

试试这个:

 bullets.RemoveAll(bullet => bullet.Offscreen()); 

最好是创建一个包含要删除的项目的列表,然后从列表中删除项目:

 List removedBullets = new List(); foreach(var bullet in bullets) { if (bullet.OffScreen()) { removedBullets.Add(bullet); } } foreach(var bullet in removedBullets) { bullets.Remove(bullet); } 

迭代“for”循环而不是迭代foreach。 这会奏效。

我以前遇到过这个问题,并在这里写博客 。

简短版本是你可以创建一个名为RemoveIf的扩展方法:

 public void RemoveIf(ICollection collection, Predicate match) { List removed = new List(); foreach (T item in collection) { if (match(item)) { removed.Add(item); } } foreach (T item in removed) { collection.Remove(item); } removed.Clear(); } 

然后只需在每次需要时与您的代理人联系:

 RemoveIf(_Entities.Item, delegate(Item i) { return i.OffScreen(); });