Hi all
By calling Push()
and Pop()
an instance of Stack<T>
in a single line I get a different behavior than performing the imho same code in two lines.
The following code snippet reproduces the behavior:
static void Main(string[] args)
{
Stack<Element> stack = new Stack<Element>();
Element e1 = new Element { Value = "one" };
Element e2 = new Element { Value = "two" };
stack.Push(e1);
stack.Push(e2);
Expected(stack); // element on satck has value "two"
//Unexpected(stack); // element on stack has value "one"
Console.WriteLine(stack.Peek().Value);
Console.ReadLine();
}
public static void Unexpected(Stack<Element> stack)
{
stack.Peek().Value = stack.Pop().Value;
}
public static void Expected(Stack<Element> stack)
{
Element e = stack.Pop();
stack.Peek().Value = e.Value;
}
The Element class is really basic:
public class Element
{
public string Value
{
get;
set;
}
}
With this code I get the following result (.NET 3.5, Win 7, fully patched):
- Calling
Expected()
(version with two lines) leaves one element on the stack withValue
set to"two"
. - When calling
Unexpected()
(Version with one line) I get one element on the stack with theValue
set to"one"
.
The only reason for the difference I could imagine was the operator precedence. As the assignment operator (=
) has the lowest precedence I see no reason why the two method should behave differently.
I also had a look at the IL generated:
.method public hidebysig static void Unexpected(class [System]System.Collections.Generic.Stack`1<class OperationOrder.Element> stack) cil managed
{
.maxstack 8
L_0000: ldarg.0
L_0001: callvirt instance !0 [System]System.Collections.Generic.Stack`1<class OperationOrder.Element>::Peek()
L_0006: ldarg.0
L_0007: callvirt instance !0 [System]System.Collections.Generic.Stack`1<class OperationOrder.Element>::Pop()
L_000c: callvirt instance string OperationOrder.Element::get_Value()
L_0011: callvirt instance void OperationOrder.Element::set_Value(string)
L_0016: ret
}
I'm not an IL crack, but for me this code still looks good ans should leave one element on the stack with value set to "two".
Can anyone explain me the reason why the method Unexpected()
does something different than Expected()
?
Thanks a lot!
Lukas