Home > Mobile >  Is the ToArray method of a Stack<T> guaranteed to return in this order?
Is the ToArray method of a Stack<T> guaranteed to return in this order?

Time:11-04

I have a Stack<T>, which I am using to stack int-tuples. Right now, I am using the following code to return a copy of the stack, sorted from oldest to newest:

public IEnumerable<Tuple<int,int>> GetAllTuples()
{
    return this.ToArray<Tuple<int,int>>().Reverse<Tuple<int,int>>();
}

This works, but I am worried that the ordering returned by ToArray() may not be guaranteed in all cases. The documentation of ToArray() states the following:

The elements are copied onto the array in last-in-first-out (LIFO) order, similar to the order of the elements returned by a succession of calls to Pop.

Is it safe to assume that in the future, calls to ToArray() (and thus by extension, .Reverse()) will return the same order? I'm a bit thrown off by "similar to". If not, how can I ensure that the tuples will be returned from oldest to newest?


To illustrate my point further, here is an example:

Stack<int> stack = new Stack<int>();
stack.Push(1);
stack.Push(2);
stack.Push(3);
stack.Push(4);
stack.Push(5);

int[] toArr = stack.ToArray<int>(); // Yields [5, 4, 3, 2, 1]
int[] toArrReverse = toArr.Reverse<int>(); // Yields [1, 2, 3, 4, 5], which is what I want.

CodePudding user response:

This piece from Microsoft documentation saying that ToArray

Copies the Stack to an array, in the same order Pop would return the items.

confirms the behavior you are observing.

    // Copies the Stack to an array, in the same order Pop would return the items.
    public virtual Object[] ToArray()
    {
        Contract.Ensures(Contract.Result<Object[]>() != null);

        Object[] objArray = new Object[_size];
        int i = 0;
        while(i < _size) {
            objArray[i] = _array[_size-i-1];
            i  ;
        }
        return objArray;
    }

Edit: When you think about it, it make sense - by definition the only way to get the items out of a stack is to Pop them (last in first out). The same should be true when all of items are being taken out (or just being copied like with ToArray). This will only happen one item at a time. If it behaves otherwise, IMHO, it will clearly violate the core idea of Stack.

CodePudding user response:

As per documentation, the elements are copied onto the array in last-in-first-out (LIFO) order, similar to the order of the elements returned by a succession of calls to Pop.

So, this looks as a strict contract which fully defines the order. There is no remarks that this is implementation specific and is a subject to change in future.

So, I believe that we can rely on the current behaviour for now and in the future.

  • Related