Search code examples
c#iteratorienumerableenumerator

Why is it.current changing his values during debug?


I'm trying to get an element at a specific index with the method :

public T GetElem(int index)
{
    var it = outerInstance.iterator();
    var i = 0;
    while (it.MoveNext() && i < index)
    {
        i++;
    }
    return it.Current;
}

I have created my own iterator which is an internal class of the outerInstance,during debug the current element is decreasing at the end it becomes null.

My test it's inside console app and looks like this :

Storage<int?> storage = new DynSLinkedList<int?>();
var ranked = new Ranked<int?>(storage);

if (ranked.IsEmpty())
{
    Console.WriteLine("is empty \n");
}

for (var i = 1; i <= 10; i++)
    ranked.Add(i);

if (!ranked.IsEmpty())
{
    Console.WriteLine("is not empty \n");
}

if (ranked.Size() == 10)
{
    Console.WriteLine("Size ok \n");
}

for (var i = 0; i <= 9; i++)
{
    var element = ranked.GetElem(i);
    if (element == 10 - i)
    {
        Console.WriteLine("get " + i + " elem ok \n");
    }
}

Only for i=0 it gets right.

enter image description here

enter image description here

I have tried to write the equivalent for the java method:

@Override
public T getElem(int index) throws IndexOutOfBoundsException {
    RWIterator<T> it=support.iterator();
    int i=0;
    while (it.hasNext() && i<index){
        it.next();
        i++;
    }
    return it.next();
}

Solution

  • Your problem is that you are using a single instance to iterate over in the Ranked.GetElem method. The first time you call ranked.GetElem, passing 0, the iterator will be moved one step (it.MoveNext).

    At this point the iterator is already pointing to the second element in your list. The next time you call ranked.GetElem, passing 1, the iterator will be moved two spaced further, ending up returning the third element as opposed to the one you are expecting (the second). So on and so forth.

    You need to either change the overall approach you are taking or reset the iterator inside the GetElem method so it always starts from the first element.

    Try this (assuming you are implementing the Reset() method correctly):

    public T GetElem(int index)
    {
        var it = outerInstance.iterator();
        it.Reset();
        var i = 0;
        while (it.MoveNext() && i < index)
        {
            i++;
        }
        return it.Current;
    }