Перегрузка Equals / GetHashCode в VB.NET для использования объектов в качестве словарных ключей

У меня есть словарь, ключи которого являются объектами Excel Range (нет, это не подлежит обсуждению), определяется следующим образом (тип CellProp является объектом, который содержит различные свойства ячейки):

Dim dic As New Dictionary(Of Excel.Range, CellProp)(New RangeComparer())

Поскольку ключи являются объектами, мне нужно перегрузить функции Equals/GetHashCode. Моя текущая реализация выглядит следующим образом:

Class RangeComparer
Implements IEqualityComparer(Of Excel.Range)
Public Overloads Function Equals(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements IEqualityComparer(Of Excel.Range).Equals
    If x.Address(External:=True) = y.Address(External:=True) Then
        Return True
    Else
        Return False
    End If
End Function
Public Overloads Function GetHashCode(ByVal obj As Excel.Range) As Integer Implements IEqualityComparer(Of Excel.Range).GetHashCode
      Return obj.Count.GetHashCode
    End Function
End Class

Тем не менее, это может быть довольно медленным при одновременном добавлении нескольких ячеек (то есть сотен) в Словарь. Самое главное, есть ли более быстрый способ сделать это? Во-вторых, почему получение хеш-кода для свойства Range в Range кажется работающим (хотя и медленно)?

1 ответ

Возможно, вы захотите немного изучить, как работают хэш-коды. Хеш-коды на 100% произвольны и определяются программистом. Единственное, что имеет значение, это то, что если два экземпляра не совпадают, то их хэш-коды должны быть разными. Если у вас есть коллекция, в которой почти все хеш-коды идентичны (т. Е. Count = 1), тогда ваш словарь по-прежнему работает просто отлично, но он превращается в линейный поиск, который очень неэффективен. Это связано с тем, что почти все экземпляры генерируют коллизии хэшей, поэтому хэширование в сегменты не дает никаких преимуществ.

Например, другой алгоритм хеширования, который вы можете попробовать, - это генерирование одного из имен ячеек, в которых должно быть намного меньше коллизий хеш-кода:

Public Overloads Function GetHashCode(ByVal obj As Excel.Range) _
    As Integer Implements IEqualityComparer(Of Excel.Range).GetHashCode

  Return obj.Address(External:=True).GetHashCode

End Function
Другие вопросы по тегам