Vb.Net Использование словарей с диапазонами Excel в качестве ключей - PullRequest
1 голос
/ 03 января 2012

Следующий код взят из более крупной процедуры (окружающий код не имеет значения).Может кто-нибудь объяснить, почему я не могу получить вторую строку ContainsKey для возврата True?Подсказка: попробуйте это на листе с несколькими заполненными ячейками, чтобы уменьшить количество циклов.

        For Each ws As Excel.Worksheet In Wb.Worksheets
            Dim dic As New Dictionary(Of Excel.Range, String)
            rngUsed = ws.UsedRange
            For Each cell As Excel.Range In rngUsed
                dic.Add(cell, "test")
                'THE FOLLOWING TWO MESSAGES SHOULD DISPLAY THE SAME RESULT, BUT DO NOT.  WHY???
                MsgBox(dic.ContainsKey(cell)) 'Returns True
                MsgBox(dic.ContainsKey(ws.Range(cell.Address))) 'Returns False
            Next
        Next

ОБНОВЛЕНИЕ: Я добавил следующий код, и он, кажется, работает:

Dim dic As New Dictionary(Of Excel.Range, String)(New MyComparer()) 'replaces line from above

Class MyComparer
Implements IEqualityComparer(Of Excel.Range)
Public Function Equals1(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements System.Collections.Generic.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 Function GetHashCode1(ByVal obj As Excel.Range) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).GetHashCode
    Return obj.Count.GetHashCode
End Function

Конечный класс

Ответы [ 2 ]

1 голос
/ 05 марта 2012
Dim dic As New Dictionary(Of Excel.Range, String)(New MyComparer()) 'replaces line from above

Class MyComparer
Implements IEqualityComparer(Of Excel.Range)
Public Function Equals1(ByVal x As Excel.Range, ByVal y As Excel.Range) As Boolean Implements System.Collections.Generic.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 Function GetHashCode1(ByVal obj As Excel.Range) As Integer Implements System.Collections.Generic.IEqualityComparer(Of Excel.Range).GetHashCode
    Return obj.Count.GetHashCode
End Function

Это решение. Обратите внимание, что GetHashCode, используемый в этом пользовательском компараторе, очень медленный, поэтому, если у кого-то есть идея ускорить это, я бы хотел услышать об этом. @competent_tech, я должен использовать объекты для ключей, поскольку нет строкового представления для диапазона, который уникален и не подлежит изменению (например, как изменяется адрес при добавлении / удалении строк, например).

1 голос
/ 03 января 2012

Когда объект используется в качестве ключа для словаря, .Net использует GetHashCode для генерации ключа, который используется в базовой хеш-таблице.Поскольку вы используете два разных объекта, вы получите разные значения.

Подробнее см. документацию MSDN .

Лучшим подходом было бы превратить диапазон встроковое представление и использовать его в качестве ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...