C#从对象列表中删除对象

我有一个对象列表,我试图通过首先检查对象中的属性来删除列表中的特定对象。

最初我使用foreach但后来意识到你在修改集合时不能使用它,所以我决定使用普通for但是后来我不知道如何编写能够完成我最初编写的代码。

我如何编写代码来完成我最初的工作?

谢谢

这是我的代码:

  public void DeleteChunk(int ChunkID) { //foreach (Chunk i in ChunkList) //{ // if (i.UniqueID == ChunkID) // { // ChunkList.Remove(i); // } //} //This won't work because here i is just an integer so i.UniqueID won't exist. for (int i = 0; i < ChunkList.Capacity; i++) { if (i.UniqueID == ChunkID) { ChunkList.Remove(i); } } } 

您可以使用linq简化此操作:

 var item = ChunkList.SingleOrDefault(x => x.UniqueId == ChunkID); if (item != null) ChunkList.Remove(item); 

您还可以执行以下操作,如果有多个匹配项也可以使用:

 ChunkList.RemoveAll(x => x.UniqueId == ChunkID); 

你正在移除然后递增,这意味着你将领先于自己。 相反,反向移除,这样你就不会弄乱你的下一个项目。

 for (int i = ChunkList.Count-1; i >=0; i--) { if (ChunkList[i].UniqueID == ChunkID) { ChunkList.RemoveAt(i); } } 

如果ChunkListList ,则可以使用RemoveAll方法:

 ChunkList.RemoveAll(chunk => chunk.UniqueID == ChunkID); 

这段代码有两个问题:

  • Capacity表示在需要resize之前列表可以包含的项目数,而不是实际计数; 你需要使用Count ,而且
  • 当您从列表中删除时,您应该向后移动,否则当两个相同的项目彼此相邻时,您可以跳过第二个项目。

你正在检查iUniqueIDi实际上是一个整数。 你应该做这样的事情,如果你想留下一个for循环。

 for (int i = 0; i < ChunkList.Capacity; i++) { if (ChunkList[i].UniqueID == ChunkID) { ChunkList.Remove(i); } } 

但是,您可以并且应该使用linq:

 ChunkList.Remove(x => x.UniqueID == ChunkID); 

最初我使用foreach但后来意识到你在修改集合时不能使用它

您可以创建集合的副本并使用ToList()进行迭代以创建要复制:

  foreach(Chunk chunk in ChunkList.ToList()) { if (chunk.UniqueID == ChunkID) { ChunkList.Remove(chunk); } } 

一种技术是创建要修改的集合的副本,根据需要更改副本,然后将最初的集合替换为末尾的副本。

您可以使用while循环删除与ChunkID匹配的项目/项目。 这是我的建议:

 public void DeleteChunk(int ChunkID) { int i = 0; while (i < ChunkList.Count) { Chunk currentChunk = ChunkList[i]; if (currentChunk.UniqueID == ChunkID) { ChunkList.RemoveAt(i); } else { i++; } } } 

首先,您使用的是Capacity而不是Count

其次,如果您需要删除一个项目,那么您可以愉快地使用循环。 您只需要确保在删除项目后突破循环,如下所示:

 int target = 4; for (int i = 0; i < list.Count; ++i) { if (list[i].UniqueID == target) { list.RemoveAt(i); break; } } 

如果要从列表中删除与ID匹配的所有项目,则会变得更加容易,因为您可以使用List.RemoveAll(Predicate match)

 int target = 4; list.RemoveAll(element => element.UniqueID == target); 

最简单的解决方案,不使用LINQ:

  Chunk toRemove = null; foreach (Chunk i in ChunkList) { if (i.UniqueID == ChunkID) { toRemove = i; break; } } if (toRemove != null) { ChunkList.Remove(toRemove); } 

(如果Chunk是一个结构体,那么你可以使用Nullable 来实现这一点。)