日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?

發布時間:2023/12/4 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚? 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IEnumerator、IEnumerable這兩個接口單詞相近、含義相關,傻傻分不清楚。
入行多年,一直沒有系統性梳理這對李逵李鬼。

最近本人在懟著why神的《其實吧,LRU也就那么回事》,方案1使用數組實現LRU,手寫算法涉及這一對接口,借此時機覆蓋這一對難纏的冤家。

IEnumerator

IEnumerator、IEnumerable接口有相似的名稱,這兩個接口通常也在一起使用,它們有不同的用途。

IEnumerator接口為類內部的集合提供了迭代方式, IEnumerator 要求你實現三個方法:

  • MoveNext方法:該方法將集合索引加1,并返回一個bool值,指示是否已到達集合的末尾。

  • Reset方法:它將集合索引重置為其初始值-1,這會使枚舉數無效。

  • Current方法: 返回position位置的當前對象

IEnumerable

IEnumerable接口為foreach迭代提供了支持,IEnumerable要求你實現GetEnumerator方法。

public?IEnumerator?GetEnumerator() {return?(IEnumerator)this; }

該用哪一個接口?

僅憑以上辭藻,很難區分兩個接口的使用場景。

IEnumerator接口定義對類中的集合類型對象的迭代方式

IEnumerable接口允許使用foreach循環進行枚舉。

因此IEnumerable接口的GetEnumerator方法會返回一個IEnumerator接口。要實現IEnumerable,你還必須實現IEnumerator。

從英文詞根上講:
IEnumerator接口代表了枚舉器,里面定義了枚舉方式,是名詞。
IEnumerable接口代表該對象具備了可被枚舉的性質,是形容詞。

總之,如果您想提供對foreach的支持,那么就先讓對象可枚舉,再談論枚舉方式,也就是說實現這兩個接口。

最佳實踐

  • 在嵌套類中實現IEnumerator,這樣你可以創建多個枚舉器。

  • 為IEnumerator的Current方法提供異常處理。
    為什么要這么做?
    如果集合的內容發生變化,則reset方法將被調用,緊接著當前枚舉數無效,您將收到一個IndexOutOfRangeException異常(其他情況也可能導致此異常)。所以執行一個Try…Catch塊來捕獲這個異常并引發InvalidOperationException異常, 提示在迭代時不允許修改集合內容。

這也正是我們常見的在foreach 里面嘗試修改迭代對象會報InvalidOperationException異常的原因。

下面以汽車列表為例實現IEnumerator IEnumerable接口

using?System; using?System.Collections; namespace?ConsoleEnum {public?class?cars?:?IEnumerable{private?car[]?carlist;//Create?internal?array?in?constructor.public?cars(){carlist=?new?car[6]{new?car("Ford",1992),new?car("Fiat",1988),new?car("Buick",1932),new?car("Ford",1932),new?car("Dodge",1999),new?car("Honda",1977)};}//private?enumerator?classprivate?class??MyEnumerator:IEnumerator{public?car[]?carlist;int?position?=?-1;//constructorpublic?MyEnumerator(car[]?list){carlist=list;}private?IEnumerator?getEnumerator(){return?(IEnumerator)this;}//IEnumeratorpublic?bool?MoveNext(){position++;return?(position?<?carlist.Length);}//IEnumeratorpublic?void?Reset(){position?=?-1;}//IEnumeratorpublic?object?Current{get{try{return?carlist[position];}catch?(IndexOutOfRangeException){throw?new?InvalidOperationException();}}}}??//end?nested?classpublic?IEnumerator?GetEnumerator(){return?new?MyEnumerator(carlist);}} }

在foreach cars的時候,可以明顯看到

  • foreach語法糖初次接觸可枚舉的cars, 實際會訪問cars實現的 GetEnumerator()方法,拿到迭代器

  • foreach每次迭代,實際會訪問迭代器的Current屬性

關注并星標我們
更多干貨及最佳實踐分享

總結

以上是生活随笔為你收集整理的2021年了,`IEnumerator`、`IEnumerable`接口还傻傻分不清楚?的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。