Zmiana zachowania metody równości dla sieci NaN
Metoda Equals(T other)
wystąpienia dla następujących typów została zaktualizowana w IEquatable<T> celu spełnienia wymagań implementacji. W rezultacie metoda obsługuje teraz poprawnie nazwę NaN. Ta zmiana gwarantuje, że typy mogą być prawidłowo używane wraz z zestawami GetHashCode
wartości , Dictionary<TKey,TValue>i innymi zestawami skrótów.
- 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>
Poprzednie zachowanie
Equals(T other)
Wcześniej metoda wystąpienia przestrzegała wymagań IEEE 754 i odroczyła implementację==
. Oznaczało to, że NaN != NaN
, nawet gdy dwie wartości NaN są bitowo identyczne.
Na przykład:
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
W przypadku kilku wymienionych typów:
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // False
Jest to problematyczne, ponieważ użycie jednego z tych typów jako klucza w słowniku oznaczało, że klucz nigdy nie może zostać rozwiązany:
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // False
Nowe zachowanie
Zachowanie jest teraz takie samo jak w przypadku pierwotnych typów zmiennoprzecinkowych, co oznacza, że ==
metody i !=
nadal są zgodne z wymaganiami IEEE 754, gdzie NaN != NaN
. Equals(T other)
Jednak metody wystąpień są zgodne z IEquatable<T> wymaganiami, NaN.Equals(NaN)
aby program .
Na przykład (bez zmian):
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
Podczas gdy w przypadku kilku wymienionych typów (drugi wiersz drukuje True
teraz ):
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // True
A w przypadku użycia w niektórych zestawach skrótów True
(dane wyjściowe są teraz drukowane):
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // True
Wprowadzona wersja
.NET 7
Typ zmiany powodującej niezgodność
Ta zmiana może mieć wpływ na zgodność binarną.
Przyczyna wprowadzenia zmiany
Poprzednia implementacja nie spełniała wymagań implementacji programu IEquatable<T> lub object.Equals(object obj)
. Spowodowało to, że objęte typy nie były używane w zestawach skrótów lub w przypadku .GetHashCode
Zalecana akcja
Jeśli wolisz poprzednie zachowanie, przełącz się na używanie polecenia ==
lub !=
zamiast Equals(T other)
.
Dotyczy interfejsów 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