跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

c#如何删除List中的元素_c#删除List中的元素最全用法总结

Remove()按值删第一个匹配项,值不存在则无操作;RemoveAt()按索引删除,越界抛ArgumentOutOfRangeException;误用Remove()无法批量删同值元素。 用
Remove()
和
RemoveAt()
删除单个元素时要注意什么 这两个方法最常用,但行为完全不同:
Remove()
按值匹配第一个相等元素并删除,
RemoveAt()
按索引删除。如果值不存在,
Remove()
什么也不做且不报错;而
RemoveAt()
索引越界会直接抛
ArgumentOutOfRangeException
。 常见错误是误用
Remove()
试图删多个同值元素——它只删第一个。比如
list.Remove(5)
遇到
[5, 5, 1]
后变成
[5, 1]
,不是预期的
[1]
。 实操建议: 确认要删的是“某个值”还是“第几个位置”,再选方法 用
RemoveAt()
前务必检查
index >= 0 && index
若需删所有匹配项,别用循环调
Remove()
(可能跳过元素),改用
RemoveAll()
批量删除必须用
RemoveAll()
,别手写 for 循环 在遍历
List
时用
for
或
foreach
调
Remove()
,极易因索引偏移漏删或越界。正确做法是把筛选逻辑交给
RemoveAll()
,它内部一次性处理,安全高效。 示例:删掉所有偶数
list.RemoveAll(x => x % 2 == 0);
注意点: 谓词函数返回
true
的元素会被删除 返回值是实际删除的元素个数,可用于校验 不能在谓词里修改
list
本身(比如再调
RemoveAll
),会抛
InvalidOperationException
对引用类型,判断依据是对象引用或重载的
Equals()
,不是简单地址比较 按条件删又想保留原顺序?
FindAll().ForEach()
不行,得用
Where().ToList()
有人想“找出要删的,再逐个删”,于是写
list.FindAll(x => x > 10).ForEach(list.Remove)
——这会出错,因为
Remove()
修改了原集合,导致
ForEach
迭代器失效。 更糟的是,即使不报错,结果也不可靠:重复值、顺序错乱、部分漏删。 正确思路是“构造新集合”而非“边查边删”: C知道 CSDN推出的一款AI技术问答工具 下载
list = list.Where(x => x <= 10).ToList();
或者用
RemoveAll()
(推荐):
list.RemoveAll(x => x > 10);
二者区别:
RemoveAll()
原地操作,内存友好,适合大列表
Where().ToList()
创建新列表,原
list
引用改变,适合需要保留旧引用场景(如被其他变量持有) LINQ 方式可链式组合(如加
OrderBy()
),
RemoveAll()
只能单条件 删除后立即访问
Count
或索引要小心线程安全
List
本身不是线程安全的。如果多个线程同时调
RemoveAll()
或混合读写,
Count
可能不准,甚至抛
InvalidOperationException
(“集合已修改”)。 没有锁的情况下,以下代码危险:
if (list.Count > 0) { var first = list[0]; }
因为
Count
检查和
[0]
访问之间可能已被其他线程删空。 解决方式: 单线程场景无需担心 多线程下要么加
lock
,要么改用
ConcurrentBag
/
ConcurrentQueue
等线程安全集合(但它们不支持随机索引) 若只是读多写少,可用
ToArray()
快照一次再操作:
var snapshot = list.ToArray();
真正容易被忽略的是:删除操作看似简单,但一旦混入循环、多线程或引用共享,行为就依赖执行时机和集合状态。动手前先明确——你要删的是“值”还是“位置”,是否允许多删,有没有并发,以及谁还在用这个
list
引用。

相关文章