Pergunta

eu tenho uma aula Person, ele implementa o método Equals() de IEquatable<Person> (também substitui Object.Equals método, vamos ignorar o método GetHashcode() por enquanto)

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;
    }
}

OK vamos começar:

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 };

Vamos falar sobre esta linha:

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

Estou com dificuldade para entender esta parte:

EqualityComparer<Person>.Default

Eu ouvi isso EqualityComparer<Person>.Default irá verificar se a classe está implementando IEquatable - levará o Equals(Person other) Método e não o Equals(object obj). tem a vantagem de evitar o boxe

enter image description here mas

o Equals(Person other) correrá com ou sem FORA EqualityComparer<Person>.Default(porque está implementando IEquatable)

Então, de que boxe estamos falando?não há!

A única vez que Equals(object obj) será executado é quando:

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

Mas Eu sou um programador!Eu nunca enviarei um object quando na verdade é um Person!

o que estou perdendo?Estou tendo problemas para entender o benefício aqui de EqualityComparer<Object>.Default.Alguém pode me dar um exemplo para provar que estou errado?

Foi útil?

Solução

Se você passar null como o segundo parâmetro ou se você não passar nenhum segundo argumento (que é basicamente o mesmo), a implementação de SequenceEquals chamará EqualityComparer<T>.Default em si (descompilar Enumerable para ver isso).Isso explica por que você não vê diferença se fornece EqualityComparer<T>.Default ou não.

Então no final o segundo parâmetro só faz sentido se você quiser usar um comparador de igualdade outro que não seja EqualityComparer<T>.Default.

Outras dicas

Que você pode passar IEqualityComparer<object>.Default é um efeito de contravariância genérica, adicionado no .NET 4.

Essencialmente, um IEqualityComparer<BaseType> pode ser usado sempre que um IEqualityComparer<DerivedType> é obrigatório, onde DerivedType : BaseType.Desde Person deriva de Object, isso significa que um IEqualityComparer<Object> pode ser usado onde quer que IEqualityComparer<Person> é necessário.

A resposta está aqui: http://msdn.microsoft.com/en-us/library/ms131187(v=vs.110).aspx

Para um tipo de valor, você deve sempre implementar IEquatable e substituir Object.Equals(Object) para obter melhor desempenho.Object.Equals enquadra os tipos de valor e depende da reflexão para comparar dois valores quanto à igualdade.Tanto a implementação de Equals quanto a substituição de Object.Equals devem retornar resultados consistentes.

Se você não substituir Equals e GetHashCode, EqualityComparer.Default cuidará disso para você.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top