C# Stack item reversal

R

RobertEstelle

Hello everyone,
I encountered an interesting bug in a program I was writing that was
caused by the following unexpected behaviour. Basically, creating a
new Stack object from another results in a reversal of the item
ordering.
Example:

Stack<string> a = new Stack<string>();
a.Push("a"); a.Push("b"); a.Push("c"); a.Push("d");
// a has "d","c","b","a"

Stack<string> b = new Stack<string>(a);
// b has "a","b","c","d"

Does anyone know why this happens? Is it a bug in the class library,
or some mistaken assumption on my part?
For background, I was using a stack for a recursive function wherein
each function call required its own copy of the initial stack to pop
items off. Needless to say, having the stack reverse itself at each
depth caused some interesting behaviour.

Looking forward to your comments;
- Robert Estelle
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Hello everyone,
I encountered an interesting bug in a program I was writing that was
caused by the following unexpected behaviour. Basically, creating a
new Stack object from another results in a reversal of the item
ordering.
Example:

Stack<string> a = new Stack<string>();
a.Push("a"); a.Push("b"); a.Push("c"); a.Push("d");
// a has "d","c","b","a"

Stack<string> b = new Stack<string>(a);
// b has "a","b","c","d"

Does anyone know why this happens? Is it a bug in the class library,
or some mistaken assumption on my part?
For background, I was using a stack for a recursive function wherein
each function call required its own copy of the initial stack to pop
items off. Needless to say, having the stack reverse itself at each
depth caused some interesting behaviour.

Looking forward to your comments;
- Robert Estelle

It's a mistaken assumption on your part. There is no constructor for the
Stack class that takes a Stack as parameter and copies it.

You are using the constructor that takes an IEnumerable. That means that
it's using a Stack.Enumerator to get the elements in the original stack.
The enumerator reads the elements in the same order as if they were
poped from the stack, and the constructor pushes them in that order. The
result is of course that the new stack is a reversed copy of the original.
 
R

RobertEstelle

Thanks -- you are correct of course, but it seems odd that the library
would choose not to overload its own constructor to allow for
"correct" functionality. Does anyone know what went into this design
decision?
 
T

Tom Spink

Thanks -- you are correct of course, but it seems odd that the library
would choose not to overload its own constructor to allow for
"correct" functionality. Does anyone know what went into this design
decision?

Because, if they did alter that particular overload to work in reverse, it
wouldn't work as expected if you did give it something you wanted to
iterate over in the correct direction. It makes more sense to have it
working as you expect it to, for the type you are giving it, in this case a
class that implements IEnumerable.

Perhaps the clone method (as noted by LM, in the adjacent reply) is more
suited to your needs.
 
?

=?ISO-8859-1?Q?G=F6ran_Andersson?=

Thanks -- you are correct of course, but it seems odd that the library
would choose not to overload its own constructor to allow for
"correct" functionality. Does anyone know what went into this design
decision?

I guess that copying a stack is not something that you would usually do,
and if you do, you should probably duplicate all the items in the stack,
not just copy the reference. In your special case where you are using
strings, you can safely copy the references as strings are immutable,
but remember that the Stack<T> class is designed for any kind of objects.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top