/// <summary> /// 自定义泛型可迭代类型 /// </summary> /// <example> /// This code shows how to build a instance of <see cref="SelfEnumerable"/>: /// <code> /// var enumerable = new SelfEnumerable<typeparam name="T">Person</typeparam>5); /// enumerable.Add(new Person() { Name = "xfh", Age = 27 }); /// </code> /// </example> /// <descript> /// 灵感来自: /// The foreach statement executes a statement or a block of statements for each element in an instance of the type /// that implements the System.Collections.IEnumerable or System.Collections.Generic.IEnumerable<T> interface. /// The foreach statement is not limited to those types and can be applied to an instance of any type that satisfies the following cond /// 1. has the public parameterless GetEnumerator method whose return type is either class, struct, or interface type, /// 2. the return type of the GetEnumerator method has the public Current property and the public parameterless MoveNext metho /// whose return type is Boolean. /// 参考了: /// https://github.com/dotnet/corefx/blob/master/src/Common/src/CoreLib/System/Span.cs /// https://docs.microsoft.com/en-us/dotnet/csharp/iterators /// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/foreach-in /// https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/yield /// </descript> public class SelfEnumerable<T> { private readonly int _capacity; private T[] _innerArray; private int _addIndex = 0; public SelfEnumerable(int capacity) { _capacity = capacity; _innerArray = new T[capacity]; } /// <summary> /// 可迭代对象中存储的对象数 /// </summary> /// <value>auto-property</value> public int Count { get; private set; } = 0; public T this[int index] => _innerArray[index]; /// <summary> /// 向可迭代对象中添加元素 /// </summary> /// <remarks>当添加的元素数超过<see cref="_capacity"/>的值时,新添加的元素会覆盖之前的值</remarks> public void Add(T item) { if (_addIndex > _capacity - 1) { _addIndex = 0; } else { Count++; } _innerArray[_addIndex] = item; _addIndex++; } public SelfEnumerator GetEnumerator() => new SelfEnumerator(this); public class SelfEnumerator { private readonly SelfEnumerable<T> _selfEnumerable; private int _seekIndex = -1; internal SelfEnumerator(SelfEnumerable<T> selfEnumerable) { _selfEnumerable = selfEnumerable; } public T Current => _selfEnumerable[_seekIndex]; public bool MoveNext() { _seekIndex++; if (_seekIndex > _selfEnumerable.Count - 1) { return false; } return true; } } }