C# Iterator迭代器的实现方式
C#发展到今天又三种方式实现迭代:
1、非泛型非 yield,这个较简单,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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();
标签:
C#
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
2015-06-18 Canvas中 drawImage绘制图片不显示