Удалить дубликаты из списка (из T) в VB.NET


Мне не удается удалить дубликаты из моего списка. Что я делаю не так?

Dim Contacts As New List(Of Person)

...

' remove duplicates '
Contacts = Contacts.Distinct(New PersonEqualityComparer).ToList

Мой компаратор равенства:

Public Class PersonEqualityComparer
    Implements IEqualityComparer(Of Person)
    Public Function Equals1(ByVal x As Person, ByVal y As Person) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of Person).Equals
        Return String.Equals(x.EmailAddress, y.EmailAddress, StringComparison.CurrentCultureIgnoreCase) AndAlso _
               String.Equals(x.GivenName, y.GivenName, StringComparison.CurrentCultureIgnoreCase) AndAlso _
               String.Equals(x.Surname, y.Surname, StringComparison.CurrentCultureIgnoreCase)
    End Function
    Public Function GetHashCode1(ByVal obj As Person) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Person).GetHashCode
        Return obj.GetHashCode
    End Function
End Class
2 2

2 ответа:

Необходимо реализовать GetHashCode1 так, чтобы любые два одинаковых объекта имели одинаковый хэш-код.

Если много неодинаковых объектов имеют один и тот же хэш-код, он будет работать намного медленнее, особенно для больших списков. Другими словами, Не меняйте его на Return 0.

В вашем случае простейшая реализация будет выглядеть следующим образом:

Return StringComparer.CurrentCultureIgnoreCase.GetHashCode(obj.EmailAddress) _
   Xor StringComparer.CurrentCultureIgnoreCase.GetHashCode(obj.GivenName) _
   Xor StringComparer.CurrentCultureIgnoreCase.GetHashCode(obj.Surname)

Если вы хотите более надежную реализацию, смотрите этот ответ.

StringBuilder sb as New StringBuilder
...concatenate all strings...
return StringComparer.CurrentCultureIgnoreCase.GetHashCode(sb.ToString())

Это, безусловно, медленнее, чем метод xor или прокатка собственной хэш-функции. Вы можете попробовать использовать это, однако, если у вас есть высокая частота столкновений из-за xoring.