NaN 的 Equals 方法行为变更
已更新以下类型的 Equals(T other)
实例方法,以满足 IEquatable<T> 实现要求。 因此,该方法现在正确处理 NaN。 此更改可确保这些类型可以与 GetHashCode
、Dictionary<TKey,TValue> 以及其他哈希集一起正确使用。
- 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>
旧行为
以前,Equals(T other)
实例方法遵循 IEEE 754 要求,并遵循 ==
实现。 这意味着 NaN != NaN
,即使两个 NaN 按位相同。
例如:
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
对于列出的几种类型:
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // False
这是有问题的,因为在字典中使用这些类型之一作为键意味着键永远无法被解析:
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // False
新行为
现在的行为与基元浮点类型的行为相同,也就是说,==
和 !=
方法继续遵循 IEEE 754 要求,其中 NaN != NaN
。 但 Equals(T other)
实例方法遵循 IEquatable<T> 要求,以便实现 NaN.Equals(NaN)
。
例如(无更改):
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
对于列出的几种类型(第二行现在输出 True
):
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // True
当在某些哈希集中使用时(输出现在显示 True
):
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // True
引入的版本
.NET 7
中断性变更的类型
此项更改可能会影响二进制兼容性。
更改原因
前面的实现不符合 IEquatable<T> 或 object.Equals(object obj)
的实现要求。 这导致受影响的类型在哈希集或 GetHashCode
中不可用。
建议的操作
如果更喜欢以前的行为,请切换到使用 ==
或 !=
而不是 Equals(T other)
。
受影响的 API
- 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