以下代码摘自较大的程序(周围的代码不相关)。任何人都可以解释为什么我无法让第二个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
结束班
答案 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,我必须使用对象作为键,因为没有字符串表示形式是唯一且不会发生变化的(例如,添加/删除行时地址如何变化)。