Vb.Net使用带有Excel范围的词典作为键

时间:2012-01-02 20:01:15

标签: vb.net excel dictionary

以下代码摘自较大的程序(周围的代码不相关)。任何人都可以解释为什么我无法让第二个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 个答案:

答案 0 :(得分:1)

当一个对象用作字典的键时,.Net使用GetHashCode生成在底层哈希表中使用的键。由于您使用的是两个不同的对象,因此您将获得不同的值。

有关详细信息,请参阅the MSDN documentation

更好的方法是将范围转换为字符串表示形式,并将其用作关键字。

答案 1 :(得分:1)

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,我必须使用对象作为键,因为没有字符串表示形式是唯一且不会发生变化的(例如,添加/删除行时地址如何变化)。