Quiz about Object.Equals()


I posted a quiz about C# equality here. It focused on equality via operator== and had questions like “what does this evaluate to: ((float) (int) x == (int) (float) x)”.

 

The key takeaway from the quiz was that after you account for reference vs. value equality, temporary objects, and conversions, it’s not always obvious when two things are equal or not. (As of the time of this writing, 3/12/05, I haven’t gotten one correct answer to that quiz) It turns out that operator== would return false when one may innocently  expect it to return true.

 

The CLR has Object.Equals() to try and simplify this. Collection classes that store System.Object instances are encouraged to use Object.Equals instead of operator== to avoid the pitfalls demonstrated in the last quiz.

 

So here’s a followup quiz. These are the same questions in the last quiz, but using Object.Equals() instead of operator==.

Given that x is a local C# variable of type ‘int,  are the following C# expressions true or false? (Assume an unchecked context)

 

  1. ( x ).Equals( x  )
  2. ( (object) x ).Equals( (object) x  )
  3. ( (System.Object) x ).Equals( (System.Object) x )
  4. ( (int) (object) x ).Equals( (int) (object) x  )
  5. ( (float) x ).Equals( (float) x  )
  6. ( (int) x ).Equals( (int) x )
  7. ( (int) x ).Equals( (float) x  )
  8. ( (float) (int) x ).Equals( (int) (float) x  )
  9. ( (System.Int32) x ).Equals( (System.Int32) x  )
  10. ( x.ToString() ).Equals( x.ToString() )
  11. ( (object) x.ToString() ).Equals( (object) x.ToString()  )

 

I’ll post the answers later.

(Update: What I thought was a potential CLR bug appears to be a C# compiler difference between the V1.0 and V2.0 CLR. Following up… )

 

Comments (5)

  1. Austin says:

    1. ( x ).Equals( x )

    True, overrides Object.Equals, and does a value comparion.

    2. ( (object) x ).Equals( (object) x )

    True, it calls Int32.Equals

    3. ( (System.Object) x ).Equals( (System.Object) x )

    True. Same as 2.

    4. ( (int) (object) x ).Equals( (int) (object) x )

    True. Box>Unbox> 1.

    5. ( (float) x ).Equals( (float) x )

    True. Precision is same for local variables.

    6. ( (int) x ).Equals( (int) x )

    True. Useless, x is already an int.

    7. ( (int) x ).Equals( (float) x )

    False. float cannot always preserve every digit.

    8. ( (float) (int) x ).Equals( (int) (float) x )

    True. Any precision lost is lost in both parts.

    9. ( (System.Int32) x ).Equals( (System.Int32) x )

    True. Same as 6.

    10. ( x.ToString() ).Equals( x.ToString() )

    True. String.Equals does a value comparison.

    11. ( (object) x.ToString() ).Equals( (object) x.ToString() )

    True. Object.Equals is virtual, so String.Equals will be called.

  2. Mike says:

    Austin – You’re very close! I think you have 1 wrong answer, and 1 correct answer but with the wrong reasoning. I’ll post the answers in a bit.

  3. In the above change #7 and #8

    #7 False but the reason is that that after boxing (float) x will preserve it’s type (i.e. "boxed float") and therefore Equal will return false

    #8 False. The explanation is reverse of #7