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