c# Yield return之简单方法实现迭代器和集合初始化器
来源:互联网 发布:建筑图js 编辑:程序博客网 时间:2024/04/28 12:52
背景:最近看 C# in Depth ,谈到初始化器的时候上面说是主要看类中的Add方法,当时第一感觉是有这么神奇,有这个方法就能实现初始化器?然后我就自己写了一个只有Add()的List,初始化的时候提示要实现IComarable,想到这本书中还谈到一个简单的方法:用yield return实现用这个接口来完成迭代器功能,一举两得,学习两个知识点。
注:List代码主要是利用了微软的原代码:http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs,cf7f4095e4de7646
第一版
class MyList<T> { private const int _defaultCapacity = 4; private T[] _items; private int _size; static readonly T[] _emptyArray = new T[0]; public MyList() { _items = _emptyArray; } public int Capacity { get { return _items.Length; } set { if (value < _size) throw new ArgumentOutOfRangeException("value"); if (value != _items.Length) { if (value > 0) { T[] newItems = new T[value]; if (_size > 0) { Array.Copy(_items, 0, newItems, 0, _size); } _items = newItems; } else { _items = _emptyArray; } } } } public void Add(T item) { if (_size == _items.Length) EnsureCapacity(_size + 1); _items[_size++] = item; } private void EnsureCapacity(int min) { if (_items.Length < min) { int newCapacity = _items.Length == 0 ? _defaultCapacity : _items.Length * 2; //if ((uint)newCapacity > Array.MaxArrayLength) newCapacity = Array.MaxArrayLength; if (newCapacity < min) newCapacity = min; Capacity = newCapacity; } }}static void Main(string[] args) { MyList<string> myList = new MyList<string> { "asdf ", "dfa" }; Console.ReadKey(); }运行的时候会提示:无法使用集合初始舒畅一初始化类型,原因是它未实现”System.Colletions.IEnumberable”。
第二版:主要是实现了System.Colletions.IEnumberable接口
class MyList<T> : IEnumerable{……//同上段代码 public Enumerator GetEnumerator() { return new Enumerator(this); } IEnumerator<T> IEnumerable<T>.GetEnumerator() { return new Enumerator(this); } System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator() { return new Enumerator(this); } public struct Enumerator : IEnumerator<T>, IEnumerator { private MyList<T> list; private int index; private T current; public Enumerator(MyList<T> list) { this.list = list; index = 0; current = default(T); } public void Dispose() { } public bool MoveNext() { MyList<T> localList = list; if ((uint)index < (uint)localList._size) { current = localList._items[index]; index++; return true; } return MoveNextRare(); } private bool MoveNextRare() { index = list._size + 1; current = default(T); return false; } public T Current { get { return current; } } object IEnumerator.Current { get { return current; } } void IEnumerator.Reset() { index = 0; current = default(T); }}
初始化器和迭代功能都可以正常使用
第三版:使用yield return完成迭代器功能
注:将上段实现迭代器代码全部用下面代码替代
public IEnumerator GetEnumerator() { return new Enumerator(this).GetEnumerator(); } public struct Enumerator : IEnumerable { private MyList<T> list; private int index; private T current; public Enumerator(MyList<T> list) { this.list = list; index = 0; current = default(T); } public void Dispose() { } public IEnumerator GetEnumerator() { for (int index = 0; index < list._size; index++) { yield return current = list._items[index]; } } }
另外如果把Add方法改名会提示:并不包含“Add”的定义
结论:yield return可以简单地实现迭代功能,大大的简化了代码,具体的奥秘还得深入学习。
0 0
- c# Yield return之简单方法实现迭代器和集合初始化器
- C# yield return 和 yield break
- C# 2.0 新特性之迭代器, Yield Return
- C# 中 yield return 和 yield break 关键字的用法
- C# 中 yield return 和 yield break 关键字的用法
- C#中的yield return 和return有什么区别
- C# yield return 返回枚举器
- C#中的yield return
- C#中的yield return
- 彻底搞懂C#之Yield Return语法的作用和好处
- C#中 yield return 与 yield break
- C#中 yield return 与 yield break
- C#中 yield return 与 yield break
- C#中的using和yield return混合使用
- C# yield return 的作用
- C#编程中yield return
- C# yield return用法分析
- C# yield return关键字理解
- DB之—— sql中 float类型和 java 中float 类型
- oracle 诊断利器之一—Procwatcher
- 说说我眼中的IT界加班文化
- DedeCMS提示Maximum execution time of 30 seconds exceeded in解决办法
- java学习day12
- c# Yield return之简单方法实现迭代器和集合初始化器
- Bitmap与DrawAble与byte[]与InputStream之间的转换工具类
- maven update后,还是找不到包提示
- 数值分析中插值方法-Lagrange插值
- IOS开发过程中的学习的知识(1)
- maven项目中添加jar包
- Android如何安装系统应用,及自己增加安装系统应用的接口
- Linux内核namespace机制
- php定义根目录,定义网址