引言
IEnumerable是可列舉的所有非泛型集合的基介面, IEnumerable包含一個方法GetEnumerator(),該方法回傳一個IEnumerator;IEnumerator提供通過Current屬性以及MoveNext()和Reset()方法來回圈訪問集合的功能,
IEnumerable 介面
公開列舉數,該列舉數支持在非泛型集合上進行簡單迭代,介面原始碼如下:
public interface IEnumerable { [DispId(-4), __DynamicallyInvokable] IEnumerator GetEnumerator(); }
IEnumerator 介面
支持對非泛型集合的簡單迭代,介面原始碼如下:
public interface IEnumerator { [__DynamicallyInvokable] bool MoveNext(); [__DynamicallyInvokable] object Current { [__DynamicallyInvokable] get; } [__DynamicallyInvokable] void Reset(); }
舉例說明
示例演示了通過實作IEnumerable和IEnumerator介面來回圈訪問自定義集合的最佳實踐,
定義一個簡單的物體類:
public class Person { public Person(string name, int age) { this.Name = name; this.Age = age; } public string Name; public int Age; }
定義一個物體類的集合,繼承IEnumerate:
public class People : IEnumerable { private Person[] _people; public People(Person[] pArray) { _people = new Person[pArray.Length]; for (int i = 0; i < pArray.Length; i++) { _people[i] = pArray[i]; } } /// <summary> /// GetEnumerator方法的實作 /// </summary> /// <returns></returns> IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public PeopleEnum GetEnumerator() { return new PeopleEnum(_people); } }
定義一個列舉器,繼承IEnumerator:
public class PeopleEnum : IEnumerator { public Person[] _people; /// <summary> /// 列舉器位于第一個元素之前直到第一個MoveNext()呼叫, /// </summary> private int position = -1; public PeopleEnum(Person[] list) { _people = list; } public bool MoveNext() { position++; return position < _people.Length; } public void Reset() { position = -1; } object IEnumerator.Current => Current; public Person Current { get { try { return _people[position]; } catch (IndexOutOfRangeException) { throw new InvalidOperationException(); } } } }
具體呼叫:
Person[] peopleArray = new Person[3] { new Person("張三", 15), new Person("李四", 18), new Person("王五", 21), }; People peopleList = new People(peopleArray); foreach (Person p in peopleList) Console.WriteLine(p.Name + "\t" + p.Age);
輸出:

其中,上邊呼叫中foreach等價于
IEnumerator enumeratorSimple = peopleList.GetEnumerator(); while (enumeratorSimple.MoveNext()) { Person p = enumeratorSimple.Current as Person; Console.WriteLine(p?.Name + "\t" + p?.Age); }
通過例子,可以得出:
- 實作一個自定義集合,繼承于IEnumerate,必須實作一個列舉器;
- C# 語言的foreach陳述句隱藏了列舉數的復雜性,因此, 建議foreach使用, 而不是直接操作列舉器;
- 列舉器可用于讀取集合中的資料,但不能用于修改基礎集合,
總結
IEnumerable代表繼承此介面的類(比如ArrayList,IList,List<T>等)可以獲取一個IEnumerator來實作列舉這個類中包含的集合中的元素的功能,是 .NET Framework 中最基本的集合訪問器,在編程中,Lambda運算式通過Select()或者Where()回傳的變數為IEnumerate<T>,此時我們可以通過foreach遍歷,希望本文對你有所幫助,下一篇介紹Lambda中的Select和Where,感興趣的朋友可以加關注,歡迎留言交流!
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/96157.html
標籤:C#
上一篇:.NET Core 下使用 Exceptionless 記錄日志
下一篇:.net反編譯原理
