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:
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().