Quiz about C# and object equality.
Here’s a silly little C# pop-quiz about equality. Given a local variable x declared of type ‘int’, what do the following C# expressions evaluate to?
- x == x
- (object) x == (object) x
- (System.Object) x == (System.Object) x
- (int) (object) x == (int) (object) x
- (float) x == (float) x
- (int) x == (int) x
- (int) x == (float) x
- (float) (int) x == (int) (float) x
- (System.Int32) x == (System.Int32) x
- x.ToString() == x.ToString()
- (object) x.ToString() == (object) x.ToString()
For bonus points, identify any additional work in each expression that’s not directly comparing equality of two integers.
[Update] To simplify, assume an unchecked context (which is the default). I've posted the answers here
[Update] If you think changing operator== to Object.Equals will solve all your problems, try this related quiz here .
Comments
- Anonymous
March 06, 2005
How would #8 function in a 64-bit environment? - Anonymous
March 06, 2005
Haven't tried these, but I'll venture a guess:
1. x == x. true. no extra work.
2. (object) x == (object) x. false. Two different objects created for boxing, integers are boxed and objects are compared.
3. (System.Object) x == (System.Object) x. false. Same as previous.
4. (int) (object) x == (int) (object) x. true. Two objects are created for boxing, integers are boxed, objects are unboxed to integers on stack and are compared.
5. (float) x == (float) x. false. I can't explain it really, but there has to be something that goes wrong with floating point numbers. It's never quite what you expect it to be.
6. (int) x == (int) x. true. no extra work.
7. (int) x == (float) x. false. A floating point variable on stack gets its value from the integer. The integer in left-x is then converted to float for comparison (my guess is that the 'more complicated number' wins) and comparison is like in #5.
8. (float) (int) x == (int) (float) x. false. right x is converted to float then to integer (both variables on stack). left x is converted to float (on stack). from then it's like #8.
9. (System.Int32) x == (System.Int32) x. true. no extra work.
10. x.ToString() == x.ToString(). true. A string is created by each integer, then both are string-compared.
11. (object) x.ToString() == (object) x.ToString(). true. Boxing like in #2, then the overridden ToString is called and comparison is like in #10.
Again, just my guesses. - Anonymous
March 06, 2005
I've gotten a few responses. I'll keep the comments that provide answers or hints moderated for now as to not give away any answers yet (since people may be tainted by accidentally seeing the comments when reading the quiz above). - Anonymous
March 06, 2005
I'm confused...you are hiding the answers? You already posted them. That is what that link is. - Anonymous
March 06, 2005
Huh? - Anonymous
March 07, 2005
Pretty Creative Mike! I saw two big themes (keeping it simple): (1) Boxing, (2) Floating point precision. I first assumed that all value-type and string comparisons would be true, so the three being cast with (object) would be false. I then assumed that because we start with int, there shouldn't be floating point errors, so I got tripped up on:
(float) (int) x == (int) (float) x
Your explanation makes sense. Neat
Tim - Anonymous
March 07, 2005
The comment has been removed - Anonymous
March 07, 2005
This is why you should never write code like this. If it isn't obvious to almost any user reading the code, that's a bad thing. :-) - Anonymous
March 08, 2005
Well, Jeff, unless you want to artificially boost your job security. ;) - Anonymous
March 08, 2005
Jeff - I totally agree that code should be clear and obvious. However, folks may run into a few issues:
1) developers may wrongly think something's obvious. All of the expressions above are very simple and innocent, so devs may think they're obvious. Yet I haven't got 1 correct answer.
2) I think these sort of expressions can naturally come up. For eg, anybody that writes their own general collection may hit these.
I think avoiding that confusion is part of the motivation for having System.Object.Equals(). - Anonymous
March 08, 2005
David - It turns out all of these are agnostic to a 64-bit envirornment. 'int' and 'float' are still 4 bytes there.