五月天青色头像情侣网名,国产亚洲av片在线观看18女人,黑人巨茎大战俄罗斯美女,扒下她的小内裤打屁股

歡迎光臨散文網 會員登陸 & 注冊

天坑,這樣一個lambda隨機取數(shù)據(jù)也有Bug

2022-12-07 07:03 作者:楊中科  | 我要投稿

前幾天,一位網友跟我說他編寫的一段很簡單的代碼遇到了奇怪的Bug,他要達到的效果是從一個List中隨機取出來一條數(shù)據(jù),代碼如下:

第2行代碼生成了一個包含10個User對象的List,這些User的Id值從0遞增到9;第3行代碼中調用List的Find方法來根據(jù)lambda表達式來查找一條數(shù)據(jù),這里通過random.Next()來獲取一個[0,10)之間的隨機數(shù),然后用這個隨機數(shù)來和Id進行比較。按照邏輯來講,F(xiàn)ind一定可以找到一條數(shù)據(jù),所以在第4行代碼中斷言user一定不為null。但是這段代碼有的時候運行正常,有的時候則會斷言失敗,從而程序拋出異常,令人不解。

當然,他的這段代碼寫的過于復雜,其實改成users[random.Next(0, 10)]就簡單又高效。但是為了揭示問題的本質,我這里繼續(xù)分析為什么用Find+lambda方法會出現(xiàn)問題。

我們查看一下Find方法的源代碼,如下:

Find方法的邏輯很簡單,就是遍歷List中的數(shù)據(jù),對于每條數(shù)據(jù)都調用match這個委托來判斷當前這條數(shù)據(jù)是否滿足條件,如果找到一條滿足條件的數(shù)據(jù),就把它返回。如果走到最后都沒有找到,就返回默認值(比如null)。這個邏輯簡單到貌似看不到任何問題。

問題的關鍵就在if (match(_items[i]))這一句代碼。它是在每一次循環(huán)都調用一下match的委托來判斷當前數(shù)據(jù)的匹配性。而match指向的委托的方法體是p => p.Id == random.Next(0, 10),也就是每次匹配判斷都要獲取一個新的隨機數(shù)來進行比較。假設在循環(huán)的時候生成的10個隨機數(shù)為:9,8,8,7,9,1,1,2,3,4,那么就會每次match(_items[i])判斷的結果都為false,從而導致最后返回null,也就是找不到任何的數(shù)據(jù)。

明白了原理之后,解決這個問題的思路就是不要在lambda中生成待比較的隨機數(shù),而是提前生成隨機數(shù),代碼如下:

同樣的原理也適用于Single()、Where()等LINQ操作。在這些操作中也要避免在lambda表達式中再進行復雜的計算,這樣不僅可以避免類似這篇文章中提到的bug,而且可以提升程序的運行效率。

歡迎閱讀我編寫的《ASP.NET Core技術內幕與項目實戰(zhàn)》,這本書的宗旨就是“講微軟文檔中沒有的內容,講原理、講實踐、講架構”。

《ASP.NET Core技術內幕與項目實戰(zhàn)》


天坑,這樣一個lambda隨機取數(shù)據(jù)也有Bug的評論 (共 條)

分享到微博請遵守國家法律
正镶白旗| 崇礼县| 望都县| 昔阳县| 扬中市| 贵南县| 团风县| 乌什县| 额敏县| 和政县| 清水县| 新平| 军事| 镇巴县| 肥东县| 吴江市| 山西省| 合阳县| 永平县| 临高县| 黎川县| 邳州市| 鄂温| 望谟县| 潼南县| 秭归县| 长海县| 黄大仙区| 荔波县| 胶南市| 廊坊市| 龙州县| 大连市| 温州市| 札达县| 怀宁县| 贵州省| 洪洞县| 贺兰县| 荆州市| 同心县|