strings - or== c#
¿Cuál es la diferencia entre IEquatable y simplemente anulando Object.Equals()? (3)
De acuerdo con MSDN :
Si implementa
IEquatable(T)
, también debe anular las implementaciones de clase base deObject.Equals(Object)
yGetHashCode
para que su comportamiento sea coherente con el delIEquatable(T).Equals
. Si anulaObject.Equals(Object)
, su implementación anulada también se llama en llamadas al método estáticoEquals(System.Object, System.Object)
en su clase. Esto garantiza que todas las invocaciones del métodoEquals
devuelvan resultados consistentes.
Por lo tanto, parece que no existe una diferencia funcional real entre los dos, excepto que se podría llamar a cualquiera de los dos, dependiendo de cómo se use la clase. Desde el punto de vista del rendimiento, es mejor utilizar la versión genérica porque no hay una penalización de box / unboxing asociada.
Desde un punto de vista lógico, también es mejor implementar la interfaz. Anular el objeto realmente no le dice a nadie que su clase es realmente equitativa. La anulación puede ser simplemente una clase de "no hacer nada" o una implementación superficial. El uso de la interfaz dice explícitamente: "¡Oye, esto es válido para la verificación de igualdad!" Es solo un mejor diseño.
Quiero que mi clase de Food
pueda probar cuando sea igual a otra instancia de Food
. Más tarde lo List.Contains()
contra una Lista, y quiero usar su método List.Contains()
. ¿Debería implementar IEquatable<Food>
o simplemente anular Object.Equals()
? Desde MSDN:
Este método determina la igualdad mediante el uso del comparador de igualdad predeterminado, tal como se define en la implementación del método IEquatable.Equals para T (el tipo de valores en la lista).
Entonces mi siguiente pregunta es: ¿qué funciones / clases del framework .NET usan Object.Equals()
? ¿Debería usarlo en primer lugar?
Extendiendo lo que Josh dijo con un ejemplo práctico. +1 a Josh - Estaba a punto de escribir lo mismo en mi respuesta.
public abstract class EntityBase : IEquatable<EntityBase>
{
public EntityBase() { }
#region IEquatable<EntityBase> Members
public bool Equals(EntityBase other)
{
//Generic implementation of equality using reflection on derived class instance.
return true;
}
public override bool Equals(object obj)
{
return this.Equals(obj as EntityBase);
}
#endregion
}
public class Author : EntityBase
{
public Author() { }
}
public class Book : EntityBase
{
public Book() { }
}
De esta manera, tengo el método reutilizable Equals () que funciona de la caja para todas mis clases derivadas.
La razón principal es el rendimiento. Cuando se introdujeron los genéricos en .NET 2.0, pudieron agregar un montón de clases ordenadas como List<T>
, Dictionary<K,V>
, HashSet<T>
, etc. Estas estructuras hacen un uso intensivo de GetHashCode
e Equals
. Pero para los tipos de valores, esto requiere boxeo. IEquatable<T>
permite que una estructura implemente un método Equals
fuertemente tipado, por lo que no se requiere boxeo. Por lo tanto, un rendimiento mucho mejor cuando se usan tipos de valores con colecciones genéricas.
Los tipos de referencia no se benefician tanto, pero la IEquatable<T>
le permite evitar un lanzamiento de System.Object
que puede marcar la diferencia si se llama con frecuencia.
Como se señaló en el blog de Jared Parson , aún debe implementar las anulaciones de objeto.