C# Linq ForEach 使用请注意

系统 1574 0

使用C# Linq的确给我们带来了很多的方便,但是如果不合理使用,会造成一些隐藏的bug,而且很难被发现。

今天我就分享一个工作中遇到的问题。


需求:对list进行遍历,把满足某一条件的item Remove掉。

    List<ClassA> list = new List<ClassA>();
for (int i = 0; i < 1000; i++)
{
    list.Add(new ClassA());
}
  
    il.ForEach(x => il.Remove(x));
  

 
为了简化代码,在此不加条件语句。

以上代码貌似是把list中所有的item都Remove掉,但其实不然。


C# Linq ForEach 使用请注意

可以看到在执行完ForEach之后list中还有500项。

想必高手们应该之后了吧?在对list进行删除的时候,list整个集合的index已经发生了变化。

Remove一次,原来集合的index就会整体向前移动一个。

 

原index:

3,4,5,6

Remove()后

index:

2,3,4,5
 

其实以上代码等价于:

    List<IA> list = new List<IA>();
for (int i = 0; i < 1000; i++)
{
    list.Add(new ClassA());
}
for (int i = 0; i < 500; i++)
{
    list.Remove(list[i]);
}
  

 
C# Linq ForEach 使用请注意

所以大家应该知道什么原因了吧?

所以应对以上bug,并且使用简介的Linq,正确的办法是:

    for (int i = 0; i <list.Count; i++)
{
    if (list[i].a==0)
    {
        list.RemoveAt(i);
        i--;
    }
}
  

 

    list.ToList().ForEach(x => {
    if (x.a==0)
    {
        list.Remove(x);
    }
});
  

ToList()会new 一个list,然后对新的list进行遍历,删除旧list中与之对应index的值,至少这样的写法是对的。但是最优的办法是使用List<T>中的RemoveAll(Predicate<T> match)方法,该方法还会return 被删除的items的个数。

    list.RemoveAll(x => x.a == 0);
  

 

C# Linq ForEach 使用请注意


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论