为什么it.current在调试期间改变他的值?

时间:2015-05-27 18:51:23

标签: c# iterator ienumerable enumerator

我正在尝试使用以下方法获取特定索引处的元素:

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

我已经创建了自己的迭代器,它是outerInstance的内部类,在调试期间当前元素在结束时它会变为空。

我的测试是在控制台应用程序中,看起来像这样:

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

只有i = 0才正确。

enter image description here

enter image description here

我试过写java方法的等价物:

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

1 个答案:

答案 0 :(得分:2)

您的问题是您使用单个实例在Ranked.GetElem方法中进行迭代。第一次调用ranking.GetElem,传递0时,迭代器将移动一步(it.MoveNext)。

此时,迭代器已经指向列表中的第二个元素。下次调用ranking.GetElem时,传递1,迭代器将进一步间隔两次移动,最后返回第三个元素而不是你期望的那个(第二个)。等等等等。

您需要更改正在采用的整体方法或重置GetElem方法中的迭代器,以便始终从第一个元素开始。

试试这个(假设你正确地实现了Reset()方法):

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