Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Equals(T other)
instance method for the following types was updated to meet the IEquatable<T> implementation requirements. As a result, the method now correctly handles NaN. This change ensures the types can correctly be used alongside GetHashCode
, Dictionary<TKey,TValue>, and other hash sets.
- System.Numerics.Matrix3x2
- System.Numerics.Matrix4x4
- System.Numerics.Plane
- System.Numerics.Quaternion
- System.Numerics.Vector2
- System.Numerics.Vector3
- System.Numerics.Vector4
- System.Numerics.Vector<T>
- System.Runtime.Intrinsics.Vector64<T>
- System.Runtime.Intrinsics.Vector128<T>
- System.Runtime.Intrinsics.Vector256<T>
Previous behavior
Previously, the Equals(T other)
instance method followed the IEEE 754 requirements and deferred to the ==
implementation. This meant that NaN != NaN
, even when the two NaN are bitwise identical.
For example:
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
While for several of the listed types:
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // False
This is problematic because using one of these types as a key in a dictionary meant that the key could never be resolved:
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // False
New behavior
The behavior is now the same as for the primitive floating-point types, which is that the ==
and !=
methods continue to follow the IEEE 754 requirements where NaN != NaN
. But the Equals(T other)
instance methods follow the IEquatable<T> requirements so that NaN.Equals(NaN)
.
For example (no change):
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
While for several of the listed types (the second line now prints True
):
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // True
And when used in some hash set (the output now prints True
):
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // True
Version introduced
.NET 7
Type of breaking change
This change can affect binary compatibility.
Reason for change
The previous implementation did not meet the implementation requirements of IEquatable<T> or object.Equals(object obj)
. This resulted in the affected types not being usable in hash sets or with GetHashCode
.
Recommended action
If you prefer the previous behavior, switch to using ==
or !=
instead of Equals(T other)
.
Affected APIs
- System.Numerics.Matrix3x2.Equals
- System.Numerics.Matrix4x4.Equals
- System.Numerics.Plane.Equals
- System.Numerics.Quaternion.Equals
- System.Numerics.Vector2.Equals
- System.Numerics.Vector3.Equals
- System.Numerics.Vector4.Equals
- System.Numerics.Vector<T>.Equals
- System.Runtime.Intrinsics.Vector64<T>.Equals
- System.Runtime.Intrinsics.Vector128<T>.Equals
- System.Runtime.Intrinsics.Vector256<T>.Equals