Cambio de comportamiento de los métodos Equals para NaN
El método de instancia Equals(T other)
de los siguientes tipos se actualizó para cumplir los requisitos de la implementación de IEquatable<T>. Como resultado, el método ahora controla NaN correctamente. Este cambio garantiza que los tipos se pueden usar correctamente junto con GetHashCode
, Dictionary<TKey,TValue> y otros conjuntos de hash.
- 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>
Comportamiento anterior
Antes, el método de instancia Equals(T other)
seguía los requisitos 754 de la IEEE y se posponía hasta la implementación ==
. Esto llevaba a NaN != NaN
, incluso cuando los dos NaN son idénticos bit a bit.
Por ejemplo:
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
Mientras que para varios de los tipos enumerados:
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // False
Esto es problemático porque el uso de uno de estos tipos como clave en un diccionario significaba que la clave nunca se podía resolver:
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // False
Comportamiento nuevo
El comportamiento es ahora el mismo que para los tipos primitivos de punto flotante: los métodos ==
y !=
siguen los requisitos 754 de la IEEE, en los que se produce NaN != NaN
. Pero los métodos de instancia Equals(T other)
siguen los requisitos de IEquatable<T> para que se produzca NaN.Equals(NaN)
.
Por ejemplo (sin cambios):
float f = float.NaN;
Console.WriteLine(f == f); // False
Console.WriteLine(f.Equals(f)); // True
Mientras que para varios de los tipos enumerados (la segunda línea ahora imprime True
):
Vector2 v = new Vector2(float.NaN);
Console.WriteLine(v == v); // False
Console.WriteLine(v.Equals(v)); // True
Y cuando se usan en algún conjunto hash (la salida ahora imprime True
):
Vector2 v = new Vector2(float.NaN);
var s = new HashSet<Vector2>();
s.Add(v);
Console.WriteLine(s.Contains(v)); // True
Versión introducida
.NET 7
Tipo de cambio importante
Este cambio puede afectar a la compatibilidad binaria.
Motivo del cambio
La implementación anterior no cumplió los requisitos de implementación de IEquatable<T> o de object.Equals(object obj)
. Esto dio lugar a que los tipos afectados no se pudieran usar en conjuntos hash o con GetHashCode
.
Acción recomendada
Si prefiere el comportamiento anterior, puede recuperarlo usando ==
o !=
en vez de Equals(T other)
.
API afectadas
- 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
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de