A strange piece of code I\'ve just discovered in C# (should also be true for other CLI languages using .NET\'s structs
).
Operator and method overloads, as well as conversion operators, are evaluated at compile time, unlike virtual-method overrides which are evaluated at run-time. The expression someIntVar.Equals(someNumericQuantity)
is completely unrelated to the expression someObjectVarThatHoldsAnInt.Equals(someNumericQuantity)
. If you were to pretend the virtual method Object.Equals
has a different name (like IsEquivalentTo
), and substitute that name every place the virtual method is used, this would be much clearer. An integer zero may be numerically equal to a long zero, but that does not mean they are semantically equivalent.
Such a separation in meaning between Equals
and IsEquivalentTo
, incidentally, would also have helped to avoid murkiness in the definition of the latter. It's possible to define a meaningful equivalence relation for arbitrary objects: storage location X
should be considered equivalent to storage location Y
if the behavior of all members of the former will always be equivalent to the corresponding members of the latter, and the only way to determine whether X
and Y
refer to the same object would be to use Reflection or ReferenceEquals
. Even though 1.0m.Equals(1.00m)
is and should be true, 1.0m.IsEquivalentTo(1.00m)
should be false. Unfortunately, the use of the same name for the object equivalency-test method and the Decimal
numerical-equality-test method led Microsoft to define the former to behave like the latter.