Question

Making portable collections I faced with need of limited IEnumerator, which will take some other enumerator and limit it with given count of items. I'm talking about some analog of IEnumerable.Take(int) from LINQ.

So I want something like:

var arr = new int[] {1, 2, 3, 4};
var originalEnumerator = arr.GetEnumerator();                   // Will enumerate 4 items
var limitedE =  new LimitedEnumerator(arr.GetEnumerator(), 2);  // Will enumerate 2 items
var limitedE2 = new LimitedEnumerator(arr.GetEnumerator(), 9);  // Will enumerate 4 items
Was it helpful?

Solution

There is already existing method Enumerable.Take which returns 'limited' enumerable.

var arr = new int[] {1, 2, 3, 4};
var originalEnumerator = arr.GetEnumerator(); // Will enumerate 4 items
var limitedE =  arr.Take(2).GetEnumerator();  // Will enumerate 2 items
var limitedE2 = arr.Take(9).GetEnumerator();  // Will enumerate 4 items

Also usually you don't need to work with enumerator directly - consider to use IEnumerable<T>.

OTHER TIPS

I've ended with these normal and Template versions of LimitedEnumerator. They are tested in all possible cases :)

public class LimitedEnumerator : IEnumerator
{
    protected readonly IEnumerator _enumerator;
    private readonly int _limit;

    private int _index;

    public LimitedEnumerator(IEnumerator enumerator, int limit)
    {
        if (enumerator == null) 
            throw new ArgumentNullException("enumerator");

        if (limit < 0)
            throw new ArgumentOutOfRangeException("limit");
        _enumerator = enumerator;
        _limit = limit;
        _index = 0;
    }

    public bool MoveNext()
    {
        var moveNext = _enumerator.MoveNext();
        if (moveNext)
            Current = _enumerator.Current;

        return moveNext && ++_index <= _limit;
    }

    public void Reset()
    {
        _index = 0;
        _enumerator.Reset();
        Current = _enumerator.Current;
    }

    public object Current { get; private set; }
}

public class LimitedEnumerator<T> : LimitedEnumerator, IEnumerator<T>
{
    public LimitedEnumerator(IEnumerator<T> enumerator, int limit) 
        : base(enumerator, limit)
    {
    }

    public void Dispose()
    {
        ((IEnumerator<T>)_enumerator).Dispose();
    }

    T IEnumerator<T>.Current
    {
        get
        {
            return (T) Current;
        }
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top