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); } }
如果ChunkList
是List
,则可以使用RemoveAll
方法:
ChunkList.RemoveAll(chunk => chunk.UniqueID == ChunkID);
这段代码有两个问题:
-
Capacity
表示在需要resize之前列表可以包含的项目数,而不是实际计数; 你需要使用Count
,而且 - 当您从列表中删除时,您应该向后移动,否则当两个相同的项目彼此相邻时,您可以跳过第二个项目。
你正在检查i
的UniqueID
而i
实际上是一个整数。 你应该做这样的事情,如果你想留下一个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
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
- Microsoft.Jet.OLEDB.4.0转换字符
- 是否可以在Socket和TcpClient对象之间进行转换?
- Windsor LifeStyle – 每个图形的共享实例
- Environment.CurrentDirectory vs System.IO.Directory.GetCurrentDirectory
- HttpClient调用Windows-Authenication ApiController方法…但没有WindowsIdentity出现
- 获取用户在浏览器中输入的确切URL
- Protobuf-net:无法创建抽象类的实例
- WPF MVVM Light – 在工作完成之前显示通知
- 如何在Selenium中设置ChromeDriver的端口?