迭代器笔记
这篇文章详细介绍了C#中List<T>类的迭代器实现,包括其主要方法和结构。以下是对文章内容的总结和解析:
1. List<T>的主要属性
- _items: 存储列表元素的数组。
- _size: 当前列表中元素的数量。
- _version: 用于检测集合是否被修改。
2. GetEnumerator方法
- 返回一个
Enumerator对象,该对象实现了IEnumerator<T>接口。
public IEnumerator<T> GetEnumerator() { return new Enumerator(this); } 3. Enumerator结构体
- list: 指向包含元素的列表。
- index: 当前枚举器的位置。
- version: 列表版本,用于检测集合是否被修改。
- current: 当前枚举到的元素。
3.1 构造函数
internal Enumerator(List<T> list) { this.list = list; index = 0; version = list._version; current = default(T); } 3.2 Dispose方法
- 不做任何操作,因为不需要释放资源。
public void Dispose() { } 3.3 MoveNext方法
- 移动到集合的下一个元素,并返回该元素。
- 如果已经到达集合末尾,则返回
false。
public bool MoveNext() { List<T> localList = list; if (version == localList._version && ((uint)index < (uint)localList._size)) { current = localList._items[index]; index++; return true; } return MoveNextRare(); } 3.4 MoveNextRare方法
- 如果集合被修改,则抛出异常。
- 否则,将索引设置为列表末尾,并返回
false。
private bool MoveNextRare() { if (version != list._version) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); } index = list._size + 1; current = default(T); return false; } 3.5 Current属性
- 返回当前枚举到的元素。
- 如果索引为0或列表末尾,则抛出异常。
public T Current { get { return current; } } 3.6 System.Collections.IEnumerator.Current属性
- 实现
IEnumerator接口的Current属性。
Object System.Collections.IEnumerator.Current { get { if (index == 0 || index == list._size + 1) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumOpCantHappen); } return Current; } } 3.7 Reset方法
- 将索引重置为开始位置。
- 如果集合被修改,则抛出异常。
void System.Collections.IEnumerator.Reset() { if (version != list._version) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EnumFailedVersion); } index = 0; current = default(T); } 总结
List<T>类通过内部的Enumerator结构体实现了迭代器,该结构体提供了对列表元素的遍历功能。MoveNext方法用于移动到下一个元素,并返回该元素;Reset方法用于重置枚举器位置。通过版本号检测机制,确保在多线程环境下对集合的线程安全操作。