tags:

views:

372

answers:

2

What is the difference between the evaluation of == and Equals in C#?

For Ex,

if(x==x++)//Always returns true

but

if(x.Equals(x++))//Always returns false 

Edited:

     int x=0;
     int y=0;

     if(x.Equals(y++))// Returns True
+4  A: 

Order of evaluation. ++ evaluates first (second example). But in the first example, == executes first.

Aliostad
i don't agree try this out, see the edited part
wiz kid
Wow! I cant believe my eyes... I will get back to you
Aliostad
@Aliostad: Sure Anytime.... but the output will remain the same, even if you come after one year...:)
wiz kid
I think the general idea of this answer is correct, for the 2nd and 3rd example: 1. The parameter to Equals is evaluated, this will "reserve" 0 as the value parameter, but it will also increment x by 1. 2. The Equals is performed. if x=0, then x.Equals(x++) becomes 1.Equals(0). The difference between the 1st and 2nd example is that == is performed before x itself is set to x+1. If you overload the operators on a struct and debug you'll see that it will actually step into ++ before ==, but it doesn't do anything with the result from ++ until after the expression in which it occurs is evaluated.
Bubblewrap
It's not order of evaluation, exactly. The target of the Equals method is evaluated first. But the result isn't the value of x (0), it's the address of x, because methods on value types receive a "this" pointer, not the value of the target.
Ben Voigt
+10  A: 

According to the specification, this is expected behavior.

The behavior of the first is governed by section 7.3 of the spec:

Operands in an expression are evaluated from left to right. For example, in F(i) + G(i++) * H(i), method F is called using the old value of i, then method G is called with the old value of i, and, finally, method H is called with the new value of i. This is separate from and unrelated to operator precedence.

Thus in x==x++, first the left operand is evaluated (0), then the right-hand is evaluated (0, x becomes 1), then the comparison is done: 0 == 0 is true.

The behavior of the second is governed by section 7.5.5:

  • If M is an instance function member declared in a value-type:
    • E is evaluated. If this evaluation causes an exception, then no further steps are executed.
    • If E is not classified as a variable, then a temporary local variable of E’s type is created and the value of E is assigned to that variable. E is then reclassified as a reference to that temporary local variable. The temporary variable is accessible as this within M, but not in any other way. Thus, only when E is a true variable is it possible for the caller to observe the changes that M makes to this.
    • The argument list is evaluated as described in §7.5.1.
    • M is invoked. The variable referenced by E becomes the variable referenced by this.

Note that value types are passed by reference to their own methods.

Thus in x.Equals(x++), first the target is evaluated (E is x, a variable), then the arguments are evaluated (0, x becomes 1), then the comparison is done: x.Equals(0) is false.

EDIT: I also wanted to give credit to dtb's now-retracted comment, posted while the question was closed. I think he was saying the same thing, but with the length limitation on comments he wasn't able to express it fully.

Ben Voigt