日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

IEnumerable 使用foreach 详解

發(fā)布時間:2025/3/18 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 IEnumerable 使用foreach 详解 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

我們先思考幾個問題:

  • 為什么在foreach中不能修改item的值?
  • 要實現(xiàn)foreach需要滿足什么條件?
  • 為什么Linq to Object中要返回IEnumerable?
  • 接下來,先開始我們的正文。

    自己實現(xiàn)迭代器

    .net中迭代器是通過IEnumerable和IEnumerator接口來實現(xiàn)的,今天我們也來依葫蘆畫瓢。

    首先來看看這兩個接口的定義:

    并沒有想象的那么復(fù)雜。其中IEnumerable只有一個返回IEnumerator的GetEnumerator方法。而IEnumerator中有兩個方法加一個屬性。

    接下來開發(fā)畫瓢,我們繼承IEnumerable接口并實現(xiàn):

    下面使用原始的方式調(diào)用:

    有朋友開始說了,我們平時都是通過foreache來取值的,沒有這樣使用過啊。好吧,我們來使用foreach循環(huán):

    為什么說基本上是等效的呢?我們先看打印結(jié)果,在看反編譯代碼。

    由此可見,兩者有這么個關(guān)系:

    我們可以回答第一個問題了“為什么在foreach中不能修改item的值?”:

    我們還記得IEnumerator的定義嗎

    ?

    接口的定義就只有g(shù)et沒有set。所以我們在foreach中不能修改item的值。

    我們再來回答第二個問題:“要實現(xiàn)foreach需要滿足什么條件?”:

    必須實現(xiàn)IEnumerable接口?NO

    我們自己寫的MyIEnumerable刪掉后面的IEnumerable接口一樣可以foreach(不信?自己去測試)。

    所以要可以foreach只需要對象定義了GetEnumerator無參方法,并且返回值是IEnumerator或其對應(yīng)的泛型。細(xì)看下圖:

    也就是說,只要可以滿足這三步調(diào)用即可。不一定要繼承于IEnumerable。有意思吧!下次面試官問你的時候一定要爭個死去活來啊,哈哈!

    yield的使用

    你肯定發(fā)現(xiàn)了我們自己去實現(xiàn)IEnumerator接口還是有些許麻煩,并且上面的代碼肯定是不夠健壯。對的,.net給我們提供了更好的方式。

    你會發(fā)現(xiàn)我們連MyIEnumerator都沒要了,也可以正常運(yùn)行。太神奇了。yield到底為我們做了什么呢?

    好家伙,我們之前寫的那一大坨。你一個yield關(guān)鍵字就搞定了。最妙的是這塊代碼:

    這就是所謂的狀態(tài)機(jī)吧!

    我們繼續(xù)來看GetEnumerator的定義和調(diào)用:

    我們調(diào)用GetEnumerator的時候,看似里面for循環(huán)了一次,其實這個時候沒有做任何操作。只有調(diào)用MoveNext的時候才會對應(yīng)調(diào)用for循環(huán):

    現(xiàn)在我想可以回答你“為什么Linq to Object中要返回IEnumerable?”:

    因為IEnumerable是延遲加載的,每次訪問的時候才取值。也就是我們在Lambda里面寫的where、select并沒有循環(huán)遍歷(只是在組裝條件),只有在ToList或foreache的時候才真正去集合取值了。這樣大大提高了性能。

    如:

    這個時候得到了就是IEnumerable對象,但是沒有去任何遍歷的操作。(對照上面的gif動圖看)

    什么,你還是不信?那我們再來做個實驗,自己實現(xiàn)MyWhere:

    現(xiàn)在看到了吧。執(zhí)行到MyWhere的時候什么動作都沒有(返回的就是IEnumerable),只有執(zhí)行到ToList的時候才代碼才真正的去遍歷篩選。

    這里的MyWhere其實可以用擴(kuò)展方法來實現(xiàn),提升逼格。(Linq的那些查詢操作符就是以擴(kuò)展的形式實現(xiàn)的)[了解擴(kuò)展方法]。

    怎樣高性能的隨機(jī)取IEnumerable中的值

    這段代碼來源《深入理解C#》,個人覺得非常妙。貼出來給大家欣賞哈。

    ?

    結(jié)束:

    demo下載:http://pan.baidu.com/s/1dE94c1b

    接下篇:《再講IQueryable<T>,揭開表達(dá)式樹的神秘面紗》

    ?

    總結(jié)

    以上是生活随笔為你收集整理的IEnumerable 使用foreach 详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。