NaN 的 Equals 方法行為變更

下列類型的 Equals(T other) 執行個體方法已更新,以滿足 IEquatable<T> 實作需求。 因此,方法現在能正確地處理 NaN。 這項變更能確保類型可正確地搭配 GetHashCodeDictionary<TKey,TValue> 和其他雜湊集一起使用。

先前的行為

過去,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