IEnumerable與IEnumerator區別


IEnumerable與IEnumerator區別

 

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}
 
public interface IEnumerator
{
    bool MoveNext();
    void Reset();
 
    Object Current { get; }
}
 
IEnumerable和IEnumerator有什么區別?這是一個很讓人困惑的問題(在很多forum里都看到有人在問這個問題)。研究了半天,得到以下幾點認識:
 
1、一個Collection要支持foreach方式的遍歷,必須實現IEnumerable接口(亦即,必須以某種方式返回IEnumerator object)。
 
2、IEnumerator object具體實現了iterator(通過MoveNext(),Reset(),Current)。
 
3、從這兩個接口的用詞選擇上,也可以看出其不同:IEnumerable是一個聲明式的接口,聲明實現該接口的class是“可枚舉(enumerable)”的,但並沒有說明如何實現枚舉器(iterator);IEnumerator是一個實現式的接口,IEnumerator object就是一個iterator。
 
4、IEnumerable和IEnumerator通過IEnumerable的GetEnumerator()方法建立了連接,client可以通過IEnumerable的GetEnumerator()得到IEnumerator object,在這個意義上,將GetEnumerator()看作IEnumerator object的factory method也未嘗不可。


IEnumerator   是所有枚舉數的基接口。   
    
  枚舉數只允許讀取集合中的數據。枚舉數無法用於修改基礎集合。   
    
  最初,枚舉數被定位於集合中第一個元素的前面。Reset   也將枚舉數返回到此位置。在此位置,調用   Current   會引發異常。因此,在讀取   Current   的值之前,必須調用   MoveNext   將枚舉數提前到集合的第一個元素。   
    
  在調用   MoveNext   或   Reset   之前,Current   返回同一對象。MoveNext   將   Current   設置為下一個元素。   
    
  在傳遞到集合的末尾之后,枚舉數放在集合中最后一個元素后面,且調用   MoveNext   會返回   false。如果最后一次調用   MoveNext   返回   false,則調用   Current   會引發異常。若要再次將   Current   設置為集合的第一個元素,可以調用   Reset,然后再調用   MoveNext。   
    
  只要集合保持不變,枚舉數就將保持有效。如果對集合進行了更改(例如添加、修改或刪除元素),則該枚舉數將失效且不可恢復,並且下一次對   MoveNext   或   Reset   的調用將引發   InvalidOperationException。如果在   MoveNext   和   Current   之間修改集合,那么即使枚舉數已經無效,Current   也將返回它所設置成的元素。   
    
  枚舉數沒有對集合的獨占訪問權;因此,枚舉一個集合在本質上不是一個線程安全的過程。甚至在對集合進行同步處理時,其他線程仍可以修改該集合,這會導致枚舉數引發異常。若要在枚舉過程中保證線程安全,可以在整個枚舉過程中鎖定集合,或者捕捉由於其他線程進行的更改而引發的異常。  


 






免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM