Pregunta

Tengo una clase Person, implementa el método Equals() de IEquatable<Person> (también anula Object.Equals método, ignoremos el método GetHashcode() por ahora)

class Person : IEquatable<Person>
{
    public string Name { get; set; }

    public bool Equals(Person other)
    {
        return this.Name == other.Name;
    }
    public override bool Equals(object obj)
    {
        var person = obj as Person;
        return person != null && person.Name == Name;
    }
}

De acuerdo, empecemos:

Person p1 = new Person() { Name = "a" };
Person p2 = new Person() { Name = "a" };

List<Person> lst1 = new List<Person>() { p1 };
List<Person> lst2 = new List<Person>() { p2 };

Hablemos de esta línea:

 bool b = lst1.SequenceEqual(lst2, EqualityComparer<Person>.Default);

Tengo un problema para entender esta parte:

EqualityComparer<Person>.Default

He oído que EqualityComparer<Person>.Default comprobará si la clase está implementando IEquatable - tomará el Equals(Person other) Método y no el Equals(object obj). tiene la ventaja de evitar el boxeo

enter image description here pero

el Equals(Person other) correrá con o sin EqualityComparer<Person>.Default(porque está implementando IEquatable)

Entonces, ¿de qué boxeo estamos hablando?¡no lo hay!

La única vez que Equals(object obj) se ejecutará es cuando:

bool b = lst1.SequenceEqual(lst2,EqualityComparer<Object>.Default);

Pero ¡Soy programador!Nunca enviaré un object cuando en realidad es un Person!

¿Qué me estoy perdiendo?Tengo problemas para entender el beneficio aquí de EqualityComparer<Object>.Default.¿Alguien puede darme un ejemplo para demostrar que estoy equivocado?

¿Fue útil?

Solución

Si pasas null como segundo parámetro o si no pasa ningún segundo argumento (que es básicamente lo mismo), la implementación de SequenceEquals llamará EqualityComparer<T>.Default mismo (descompilar Enumerable para ver esto).Eso explica por qué no ves una diferencia si proporcionas EqualityComparer<T>.Default O no.

Entonces, al final, el segundo parámetro solo tiene sentido si quieres usar un comparador de igualdad. otro que EqualityComparer<T>.Default.

Otros consejos

que puedes pasar IEqualityComparer<object>.Default es un efecto de contravarianza genérica, agregado en .NET 4.

Esencialmente, un IEqualityComparer<BaseType> se puede utilizar siempre que un IEqualityComparer<DerivedType> es requerido, donde DerivedType : BaseType.Desde Person deriva de Object, esto significa que un IEqualityComparer<Object> se puede utilizar dondequiera que IEqualityComparer<Person> se requiere.

La respuesta está aquí: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

Para un tipo de valor, siempre debe implementar IEquatable y anular Object.Equals(Object) para obtener un mejor rendimiento.Object.Equals encuadra los tipos de valores y se basa en la reflexión para comparar la igualdad de dos valores.Tanto su implementación de Equals como su anulación de Object.Equals deberían arrojar resultados consistentes.

Si no anula Equals y GetHashCode, EqualityComparer.Default realmente se encarga de eso por usted.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top