开发者

IEnumerator moving back to record

I have requirement in which I have to back and fort开发者_如何学Go with record. So I am using IEnumerator to that. But I can move forward by movenext but there no way to move back


Here's one way you could wrap an IEnumerator<T>, by capturing its contents in a List<T> as it moves along:

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; }
    }
}

Then I would expose this kind of enumerator using an extension method:

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());
    }
}

Note that this is definitely overkill if the collection you're dealing with is already an indexed collection such as a T[] or a List<T>. It makes more sense for scenarios such as when you're enumerating over a sequence that isn't already in a conveniently indexed form and you want to be able to go backwards as well as forwards.


The IEnumerator (and IEnumerator<T>) interfaces only implement a forward only enumerator. You'll need to make your own class or interface if you want to allow bi-directional iteration through your collection.


You can't go backwards with IEnumerator. Either suck the entire set into a List or cache the current element on each pass through the loop, so it's available to the next pass.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜