有時ReSharper的警告一下:IEnumerable的ReSharper的示例代碼
的可能多個枚舉
有an SO question on how to handle this issue,並ReSharper的網站也解釋了事情here。它有一些示例代碼,告訴你這樣做,而不是:
IEnumerable<string> names = GetNames().ToList();
我的問題是關於這個具體建議:不會這還導致通過集合中的2-每個循環枚舉兩次?
有時ReSharper的警告一下:IEnumerable的ReSharper的示例代碼
的可能多個枚舉
有an SO question on how to handle this issue,並ReSharper的網站也解釋了事情here。它有一些示例代碼,告訴你這樣做,而不是:
IEnumerable<string> names = GetNames().ToList();
我的問題是關於這個具體建議:不會這還導致通過集合中的2-每個循環枚舉兩次?
GetNames()
返回IEnumerable
。所以,如果你存儲結果:
IEnumerable foo = GetNames();
然後每次枚舉foo
時,GetNames()
方法再次被調用(不誇張地說,我無法找到一個鏈接,正確解釋的細節,但看到IEnumerable.GetEnumerator()
)。
ReSharper的看到了這一點,並通過在列表中去實現它建議你存儲在一個局部變量枚舉GetNames()
,例如的結果:
IEnumerable fooEnumerated = GetNames().ToList();
這將確保該GetNames()
結果只列舉一次,只要你參考fooEnumerated
。
這件事情確實是因爲你通常要一次列舉,例如當GetNames()
執行(慢)數據庫調用。
因爲你物化結果在列表中,你再次列舉fooEnumerated
兩次都沒關係;您將兩次遍歷內存列表。
是的,你會毫無疑問地列舉兩次。但問題是,如果GetNames()
返回一個懶惰的LINQ查詢這是計算則非常昂貴,將計算兩次沒有到ToList()
或ToArray()
通話。
GetNames()
不會被調用兩次。每次您想要使用foreach
來枚舉集合時,都會調用IEnumerable.GetEnumerator()
的實現。如果在IEnumerable.GetEnumerator()
內進行了一些昂貴的計算,這可能是一個需要考慮的原因。
我發現這是理解多個枚舉的最好也是最簡單的方法。
C#LINQ:IEnumerable的
的https://helloacm.com/c-linq-possible-multiple-enumeration-of-ienumerable-resharper/
你可以在這裏指出你的鏈接的特殊點,但鏈接很不錯 - > +1 – LuckyLikey
這是一個很好很容易解釋的例子! – decompiled
啊可能的多個枚舉!這解釋了它。 – user2250250
否。只有在foreach循環中調用GetEnumerator()方法一次。真正的原因是髒數據的風險。例如,在GetNames()中,有一個SQL查詢,但只有返回IEnurable的查詢。當調用.ToList()時,將所有數據存儲在內存中,髒數據的風險很小。但是如果在2次循環之間有很多時間,如果每次都對數據庫執行SQL,那麼髒數據的風險很大。 –
@SunRobin這是一個以簡化形式呈現真相的答案,正如也在其中提到的那樣。我還沒有到處去改進它。您使用「髒數據」可能需要進一步解釋。 – CodeCaster