使用C# Linq的確給我們帶來了很多的方便,但是如果不合理使用,會造成一些隱藏的bug,而且很難被發(fā)現(xiàn)。
今天我就分享一個工作中遇到的問題。
需求:對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掉,但其實不然。
可以看到在執(zhí)行完ForEach之后list中還有500項。
想必高手們應(yīng)該之后了吧?在對list進行刪除的時候,list整個集合的index已經(jīng)發(fā)生了變化。
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]); }
所以應(yīng)對以上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中與之對應(yīng)index的值,至少這樣的寫法是對的。但是最優(yōu)的辦法是使用List<T>中的RemoveAll(Predicate<T> match)方法,該方法還會return 被刪除的items的個數(shù)。
list.RemoveAll(x => x.a == 0);
?
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯(lián)系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
