When is == not Equals()?

(non-WF post)

I had a debugging experience which was mildly shocking today. Here is some Assert-like code.

 

                object castValue = TypeCasting.DynamicCast(propertyValue, expectedType, false);

                if (expectedValue != castValue)
                {
                    throw new Exception("Property value was not equal to expected");
                }

While debugging, I was hitting a breakpoint on the throw statement. Here is what my watch window looks like:

image

What was weird? I thought that C# was converting == statements into .Equals() calls automatically. But if we look at MSIL, this is definitely not the case, it is converted to a CEQ operation, which doesn’t know it is dealing with boxed ints - from CEQs point of view, boxed ints are just objects, to do reference equality comparison on.

[Yes, I was misunderstanding the C# language semantics. Why was I thinking that way? Possibly it was that there is some case I previously encountered where .Equals() does end up getting called, but that would probably be by operator overloading, rather than overriding .Equals()…?]

Moral of the story: == is fine for known types, but when dealing with unknown types (and potential boxing) you should probably be using Object.Equals().