Udostępnij za pośrednictwem


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 GetHashCodewartości , Dictionary<TKey,TValue>i innymi zestawami skrótów.

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 Trueteraz ):

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

Jeśli wolisz poprzednie zachowanie, przełącz się na używanie polecenia == lub != zamiast Equals(T other).

Dotyczy interfejsów API