C#發展到今天又三種方式實現迭代:
1、非泛型非 yield,這個較簡單,代碼如下:
using System; using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { public class MyIterator:IEnumerable { public int[] testInt = new int[3] { 2, 56, 34 }; public IEnumerator GetEnumerator() { return new MyEnumerator(this); } private class MyEnumerator : IEnumerator { private int currentIndex = -1; private int[] dataSource; public MyEnumerator(MyIterator mit) { this.dataSource = mit.testInt; } public bool MoveNext() { currentIndex++; return currentIndex < this.dataSource.Length; } public object Current { get { return this.dataSource[currentIndex]; } } public void Reset() { currentIndex = 0; } } } }
調用:
MyIterator mi = new MyIterator(); foreach (int i in mi) { Console.WriteLine(i); } Console.ReadLine();
2、泛型方法實現,這個要寫的代碼比較多:
using System; using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { public class MyIteratorGener : IEnumerable<int> { public int[] testInt = new int[3] { 2, 56, 34 }; //實現的是泛型接口 IEnumerable<int> 里面的 IEnumerator<T> GetEnumerator(); public IEnumerator<int> GetEnumerator() { return new MyEnumerator(this); } //由於 IEnumerable<int>繼承IEnumerable,所以要實現IEnumerator GetEnumerator(); 這個,不然會報錯 System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { throw new NotImplementedException(); } private class MyEnumerator : IEnumerator<int>, IDisposable { private int currentIndex = -1; private int[] dataSource; public MyEnumerator(MyIteratorGener mit) { this.dataSource = mit.testInt; } public bool MoveNext() { currentIndex++; return currentIndex < this.dataSource.Length; } //實現的是IEnumerator< T> 中的 T Current { [__DynamicallyInvokable] get; } public int Current { get { return this.dataSource[currentIndex]; } } // 由於IEnumerable<T>繼承IEnumerable,兩個接口的GetEnumerator方法同名 // 所以對於非泛型的IEnumerable的GetEnumerator方法使用顯式接口實現。 // (如果IEnumerable<T>沒有繼承IEnumerable,那么一個只支持使用非泛型IEnumerable的 // 方法將無法使用IEnumerable<T>)
//不然會報錯,未實現 object Ienumerator.Current
object IEnumerator.Current { get { return this.dataSource[currentIndex]; } } public void Reset() { currentIndex = 0; } // IEnumerator<T>繼承了IDisposable,為了遍歷完后清理狀態,所以需要實現該方法 // 該方法在foreach循環完畢后自動調用 public void Dispose() { } } } }
調用:
MyIteratorGener mi = new MyIteratorGener(); foreach (int i in mi) { Console.WriteLine(i); } Console.ReadLine();
3、Yield return實現。C#2.0才可以 使用 yield break 結束一個迭代.
using System; using System.Collections.Generic; using System.Collections; using System.Linq; using System.Text; using System.Threading.Tasks; namespace ConsoleApplication3 { public class MyIteratorYield:IEnumerable { public IEnumerator GetEnumerator() { yield return 2; yield return 56; yield return 34; } } }
調用:
MyIteratorYield mi = new MyIteratorYield(); foreach (int i in mi) { Console.WriteLine(i); } Console.ReadLine();