IEnumerator搬回记录

Gai*_*ter 2 .net c#

我要求我必须以记录的方式支持和堡垒.所以我正在使用IEnumerator.但我可以通过movenext前进,但没有办法退回去

Dan*_*Tao 15

这是一种可以包装的方法IEnumerator<T>,通过在List<T>移动过程中捕获其内容:

public interface ITwoWayEnumerator<T> : IEnumerator<T>
{
    bool MovePrevious();
}

public class TwoWayEnumerator<T> : ITwoWayEnumerator<T>
{
    private IEnumerator<T> _enumerator;
    private List<T> _buffer;
    private int _index;

    public TwoWayEnumerator(IEnumerator<T> enumerator)
    {
        if (enumerator == null)
            throw new ArgumentNullException("enumerator");

        _enumerator = enumerator;
        _buffer = new List<T>();
        _index = -1;
    }

    public bool MovePrevious()
    {
        if (_index <= 0)
        {
            return false;
        }

        --_index;
        return true;
    }

    public bool MoveNext()
    {
        if (_index < _buffer.Count - 1)
        {
            ++_index;
            return true;
        }

        if (_enumerator.MoveNext())
        {
            _buffer.Add(_enumerator.Current);
            ++_index;
            return true;
        }

        return false;
    }

    public T Current
    {
        get
        {
            if (_index < 0 || _index >= _buffer.Count)
                throw new InvalidOperationException();

            return _buffer[_index];
        }
    }

    public void Reset()
    {
        _enumerator.Reset();
        _buffer.Clear();
        _index = -1;
    }

    public void Dispose()
    {
        _enumerator.Dispose();
    }

    object System.Collections.IEnumerator.Current
    {
        get { return Current; }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我将使用扩展方法公开这种枚举器:

public static class TwoWayEnumeratorHelper
{
    public static ITwoWayEnumerator<T> GetTwoWayEnumerator<T>(this IEnumerable<T> source)
    {
        if (source == null)
            throw new ArgumentNullExceptions("source");

        return new TwoWayEnumerator<T>(source.GetEnumerator());
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,如果您正在处理的集合已经是索引集合(例如a T[]或a),那么这绝对是一种过度杀伤List<T>.对于诸如当您对尚未以方便索引形式进行的序列进行枚举并且您希望能够向后以及向前进行的方案时,它更有意义.