{C#} 關于List<T>的迭代器需要知道的一些事

List<T> 實現(xiàn)了三個獲取迭代器方法得湘,一個是類自身的方法,兩個是顯示的接口實現(xiàn):

public List<T>.Enumerator GetEnumerator()
IEnumerator<T> IEnumerable<T>.GetEnumerator()
IEnumeraotr IEnumerable.GetEnumerator()

這三個方法的內(nèi)部實現(xiàn)都是一樣的:

return new List<T>.Enumerator(this);

那么問題來了闲礼,當我們寫下如下的 foreach#1時读宙,發(fā)生了什么?

foreach#1 
List<TNode> listthings;
foreach(var thing in listthings)

想要清楚的解釋這個問題懈词,就涉及到 foreach 的機制蛇耀。當我們寫下 foreach(E e in C)時,首先檢查的是 C 是否有 GetEnumerator 方法坎弯,如果有纺涤,再檢查 GetEnumerator 返回的類型是否實現(xiàn)了 MoveNext 方法和 Current 屬性。如果有抠忘, foreach 將直接使用這些方法和屬性撩炊。 如果前面檢查的不成立,才會嘗試將 C 轉(zhuǎn)換成 IEnumerable崎脉。
然后我們會過來看上面的問題拧咳,List<T> 有 GetEnumerator 方法。那么它返回的 List<T>.Enumerator 是個什么東東呢囚灼?

public strcut Enumerator : IEnumerator<T>, IDisposable, 

IEnumerator
首先它是個 struct骆膝,沒錯,value type灶体。 當你使用 List<T>時阅签,請時刻記住這一點。

public T Current {get;}
public bool MoveNext();

其次它符合了上面提到的檢查第二點赃春,所以 foreach愉快地采用了 listthings.GetEnumerator愉择。

為什么 Enumerator 是 struct?
為了效率劫乱,當你用完 foreach织中,Enumerator 便可自動銷毀锥涕,不用等到 GC。BCL 在做了大量研究之后采用了這一策略狭吼。
不過這一點既有好處层坠,又有很容易就踩的坑〉篌希坑是什么破花,沒錯,就是裝箱疲吸。

我們再來看看 foreach#2

foreach#2
var iter = listthings as IEnumerable;
foreach(var thingobj in iter)

var iter2 = listthings as IEnumerable<TNode>;
foreach(var thing in iter2)

將 List<T>.Enumerator 轉(zhuǎn)為 IEnumeraotr 時座每,就完成了裝箱。 當然平時我們不會直接做這個轉(zhuǎn)換摘悴,但寫如下的代碼卻是很 easy:

void PrintAddress(IEnumerable<Address> addresslist)
{
    foreach(var adr in addresslist)
}

PrintAddress(List<Address>)

如此很難直覺的看出有裝箱問題峭梳。又比如寫起來很順手的 Linq: listOfAddress.First() 等等。

所以在性能要求高的地方蹂喻,應避免使用 IList葱椭,Linq. 直接使用 List,避免 GC 帶來的壓力口四。

關于List<T>.Enumerator的實現(xiàn)細節(jié)孵运,還有很多有意思的地方。請參考鏈接:
http://marcinjuraszek.com/2013/10/playing-around-with-listt-part-two-ienumerable-and-ienumerablet-implementation.html

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蔓彩,一起剝皮案震驚了整個濱河市治笨,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌赤嚼,老刑警劉巖大磺,帶你破解...
    沈念sama閱讀 207,113評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異探膊,居然都是意外死亡杠愧,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評論 2 381
  • 文/潘曉璐 我一進店門逞壁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來流济,“玉大人,你說我怎么就攤上這事腌闯∩粒” “怎么了?”我有些...
    開封第一講書人閱讀 153,340評論 0 344
  • 文/不壞的土叔 我叫張陵姿骏,是天一觀的道長糖声。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么蘸泻? 我笑而不...
    開封第一講書人閱讀 55,449評論 1 279
  • 正文 為了忘掉前任琉苇,我火速辦了婚禮,結(jié)果婚禮上悦施,老公的妹妹穿的比我還像新娘并扇。我一直安慰自己,他們只是感情好抡诞,可當我...
    茶點故事閱讀 64,445評論 5 374
  • 文/花漫 我一把揭開白布穷蛹。 她就那樣靜靜地躺著,像睡著了一般昼汗。 火紅的嫁衣襯著肌膚如雪肴熏。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,166評論 1 284
  • 那天顷窒,我揣著相機與錄音扮超,去河邊找鬼。 笑死蹋肮,一個胖子當著我的面吹牛出刷,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坯辩,決...
    沈念sama閱讀 38,442評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼馁龟,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了漆魔?” 一聲冷哼從身側(cè)響起坷檩,我...
    開封第一講書人閱讀 37,105評論 0 261
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎改抡,沒想到半個月后矢炼,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,601評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡阿纤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,066評論 2 325
  • 正文 我和宋清朗相戀三年句灌,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片欠拾。...
    茶點故事閱讀 38,161評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡胰锌,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出藐窄,到底是詐尸還是另有隱情资昧,我是刑警寧澤,帶...
    沈念sama閱讀 33,792評論 4 323
  • 正文 年R本政府宣布荆忍,位于F島的核電站格带,受9級特大地震影響撤缴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜叽唱,卻給世界環(huán)境...
    茶點故事閱讀 39,351評論 3 307
  • 文/蒙蒙 一屈呕、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧尔觉,春花似錦凉袱、人聲如沸芥吟。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,352評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钟鸵。三九已至钉稍,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間棺耍,已是汗流浹背贡未。 一陣腳步聲響...
    開封第一講書人閱讀 31,584評論 1 261
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留蒙袍,地道東北人俊卤。 一個月前我還...
    沈念sama閱讀 45,618評論 2 355
  • 正文 我出身青樓,卻偏偏與公主長得像害幅,于是被迫代替她去往敵國和親消恍。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 42,916評論 2 344

推薦閱讀更多精彩內(nèi)容

  • 最近工作上遇到了一個性能優(yōu)化的問題以现,程序批量提交2000行數(shù)據(jù)狠怨,導致將近10分鐘才執(zhí)行完畢。拿到這樣的性能問題邑遏,首...
    圣杰閱讀 3,448評論 2 4
  • 版權聲明:本文為博主原創(chuàng)文章佣赖,歡迎轉(zhuǎn)載。請保留博主鏈接:http://blog.csdn.net/andrewfa...
    AndrewFan閱讀 2,017評論 2 11
  • 應用程序還需要操作存儲在其他數(shù)據(jù)源(如SQL數(shù)據(jù)庫或XML文件)中的數(shù)據(jù)记盒,甚至通過Web服務訪問它們憎蛤。傳統(tǒng)上,查詢...
    CarlDonitz閱讀 585評論 0 0
  • 1. 開發(fā)過程 開發(fā)過程是錯誤和缺陷開始的地方纪吮。使用工具可以幫助你在發(fā)布之后蹂午,解決掉一些問題。 編碼標準 遵照編碼...
    lichengjin閱讀 416評論 0 1
  • 第一次彬碱,走了兩萬多步豆胸,也第一次占領了封面。 雄占上風的感覺巷疼,真的很好晚胡。 跟華燕一路吃吃喝喝走走灵奖。 直到吃完了酸菜魚...
    減肥的女孩閱讀 140評論 0 1