The reason for the difference is simple, if not obvious.
If you use the equality operator ==
, then you're using the IEEE test for equality.
If you're using the Equals(object)
method, then you have to maintain the contract of object.Equals(object)
. When you implement this method (and the corresponding GetHashCode
method), you have to maintain that contract, which is different from the IEEE behaviour.
If the Equals
contract was not upheld, then the behaviour of hash tables would break.
var map = new Dictionary<double,string>();
map[double.NaN] = "NaN";
var s = map[double.NaN];
If !double.NaN.Equals(double.NaN)
, you'd never get your value out of the dictionary!
If the previous sentence does not make sense, then understand that the mechanics of hashing (used in Dictionary<T,U>
, HashSet<T>
, etc) use both the object.Equals(object)
and object.GetHashCode()
methods extensively, and rely upon guarantees of their behaviour.
double
s aren’t references and you’re not even boxing sinceSystem.Double.Equals
is overloaded. – Aggapperafloat
. – AudlyEquals
, you have to maintain a contract. See my answer. – Bullough==
, c# chose the former, forEquals
C# chose the latter. – Superphosphatedouble.NaN.Equals(float.NaN)
is true, butfloat.NaN.Equals(double.NaN)
is false. Well... actually, it's not funny. – Blanca