c# 中实现了IEnumerable接口的类型为可迭代类型。即可利用foreach遍历的类型。
可通过一下两种方式实现自定义的可迭代类型:
1. 手动实现IEnumerator接口(实现其中的 Current属性, MoveNext方法, Reset方法);
具体实现代码如下:
public class IterationSample : IEnumerable
{
public object[] Values;
public int StartingPoint;
public IterationSample(object[] values, int startingPoint)
{
this.Values = values;
this.StartingPoint = startingPoint;
}
public IEnumerator GetEnumerator()
{
return new IterationSampleIterator(this);
}
}
public class IterationSampleIterator : IEnumerator
{
private readonly IterationSample _parent;
private int _position;
internal IterationSampleIterator(IterationSample parent)
{
this._parent = parent;
this._position = -1;
}
public object Current
{
get
{
if (_position == -1 || _position == _parent.Values.Length)
{
throw new InvalidOperationException();
}
int index = _position + _parent.StartingPoint;
index = index % _parent.Values.Length;
return _parent.Values[index];
}
}
public bool MoveNext()
{
if (_position != _parent.Values.Length)
{
_position++;
}
return _position < _parent.Values.Length;
}
public void Reset()
{
_position = -1;
}
}
2. 通过IEnumerator的等价代码——yield return 来实现可迭代类型。
return 一般起到作用: 返回, 中断执行;
yield return 并不是中断,而是暂停。在下一次调用yield迭代块的时候继续执行。
具体代码实现如下:
public class IterationSampleYield : IEnumerable
{
public object[] Values;
public int StartingPoint;
public IterationSampleYield(object[] values, int startingPoint)
{
this.Values = values;
this.StartingPoint = startingPoint;
}
public IEnumerator GetEnumerator()
{
for (int index = 0; index < Values.Length; index++)
{
yield return Values[(index + StartingPoint) % Values.Length];
}
}
}