Home > Mobile >  Conversion from C to C# - Iterator issue
Conversion from C to C# - Iterator issue

Time:11-20

Please help.

I have to convert some old C code to C# and have problems with an iterator conversion. Here's the C code:

// list<int> myList
for(list<int>::iterator iter = myList.begin(); iter != myList.end() and not end;)
{
    int element = *it;
    //
    ... do something
    //                       
    iter  ;
    if(not end)
    {
        myList.push_back(element);
        myList.pop_front();
    }
}

I tried to convert it directly 1:1 to C# ...

// List<int> myList;
foreach (int element in myList)
{
    //
    ... do something
    //                       
    if (!end)
    {
        myList.Add(element);
        myList.RemoveAt(0);
    }
}

... but I got an InvalidOperationException, complaining the iterator won't work as the list is modified with Add/RemoveAt...

So my second attempt is to do it without the iterator:

// List<int> myList;
for (int iter = 0; iter < myList.Count && !end;)
{
    int element = myList[it];
    //
    ... do something
    //                       
    iter  ;
    if (!end)
    {
        myList.Add(element);
        myList.RemoveAt(0);
    }
}

But now I'm not sure if the C# code will exactly behave the same as the C code? What will happen to the iterator in C when using push_back and pop_front? Will it stay on the same element? Or do I need to adapt the C# code and execute another iter next to Add/RemoveAt?

CodePudding user response:

If you use an enumerator (implicitly via foreach or explicitly via GetEnumerator) then you are limited to not being able to modify the collection. Also, as ALX23z pointed out, the equivalent in C# to std::list is LinkedList, not List:

        LinkedList<int> myList = new LinkedList<int>();
        myList.AddLast(1);
        myList.AddLast(2);
        myList.AddLast(3);
        bool end = false;
        for (int iter = 0; iter < myList.Count && !end; iter  )
        {
            int element = myList.ElementAt(iter);

            //
            //... do something
            //                       

            if (end)
                break;

            myList.AddLast(element);
            myList.RemoveFirst();
        }

CodePudding user response:

A Queue seems like it does what you're looking for. I may be misreading it but I think the C example doesn't exit until end is set to true because myList.end() keeps being set one element further when they are pushed back.

Queue<int> intQueue = new Queue<int>(new int[]{1, 2, 3});
for(bool end = false; !end && intQueue.TryPeek(out int element);)
{
    //do stuff
    if(end) break;
    intQueue.Enqueue(intQueue.Dequeue());
}
  •  Tags:  
  • c# c
  • Related