dictionay.contains does not call overloads overrides Equals method

D

Dot net work

Hello,

My simple code is here:

Public Class MyDictionary
Inherits System.Collections.DictionaryBase

Private Class MyElement
Public Overloads Overrides Function Equals(ByVal obj As Object) As Boolean
End Function
End Class

Public Sub Add(<params>)
If Not dictionary.Contains(MyElementObject) Then
End If
End Sub
End Class


Do you know why the Equals method never gets called please?

Thank you, regards, dnw.
 
J

Jay B. Harlow [MVP - Outlook]

Dnw,
Does MyElementObject represent a Value or a Key in the Dictionary?

Within DictionaryBase 'dictionary.Contains' "determines whether the
IDictionary contains an element with the specified key", hence if
MyElementObject represents a Value, Contains is always going to return
false...

If MyElementObject represents a Key, then it needs to override both
Object.Equals & Object.GetHashCode, as a Dictionary requires both to be
implemented.

For example:

Dim dictionary As New Hashtable
dictionary.Add(New KeyPair("A", "B"), "A value")
Debug.WriteLine(dictionary.Contains(New KeyPair("A", "B")),
"contains key pair")
Debug.WriteLine(dictionary.Contains("A value"), "contains a value")


Public Class KeyPair

Private ReadOnly m_value1 As String
Private ReadOnly m_value2 As String

Public Sub New(ByVal value1 As String, ByVal value2 As String)
m_value1 = value1
m_value2 = value2
End Sub

Public Overrides Function GetHashCode() As Integer
Return m_value1.GetHashCode() Xor m_value2.GetHashCode()
End Function

Public Overloads Overrides Function Equals(ByVal obj As Object) As
Boolean
If Not TypeOf obj Is KeyPair Then Return False
Dim other As KeyPair = DirectCast(obj, KeyPair)
Return m_value1 = other.m_value1 AndAlso m_value2 =
other.m_value2
End Function

End Class

Also its better that Equals & GetHashCode are based on readonly fields as I
have done above, otherwise you run the risk of returning inconsistent values
for Equals & GetHashCode which will cause even more confusion (for the
dictionary & you).

Hope this helps
Jay
 
D

Dot net work

Awesome! You are a ninja programmer!

Jay B. Harlow said:
Dnw,
Does MyElementObject represent a Value or a Key in the Dictionary?

Within DictionaryBase 'dictionary.Contains' "determines whether the
IDictionary contains an element with the specified key", hence if
MyElementObject represents a Value, Contains is always going to return
false...

If MyElementObject represents a Key, then it needs to override both
Object.Equals & Object.GetHashCode, as a Dictionary requires both to be
implemented.

For example:

Dim dictionary As New Hashtable
dictionary.Add(New KeyPair("A", "B"), "A value")
Debug.WriteLine(dictionary.Contains(New KeyPair("A", "B")),
"contains key pair")
Debug.WriteLine(dictionary.Contains("A value"), "contains a value")


Public Class KeyPair

Private ReadOnly m_value1 As String
Private ReadOnly m_value2 As String

Public Sub New(ByVal value1 As String, ByVal value2 As String)
m_value1 = value1
m_value2 = value2
End Sub

Public Overrides Function GetHashCode() As Integer
Return m_value1.GetHashCode() Xor m_value2.GetHashCode()
End Function

Public Overloads Overrides Function Equals(ByVal obj As Object) As
Boolean
If Not TypeOf obj Is KeyPair Then Return False
Dim other As KeyPair = DirectCast(obj, KeyPair)
Return m_value1 = other.m_value1 AndAlso m_value2 =
other.m_value2
End Function

End Class

Also its better that Equals & GetHashCode are based on readonly fields as I
have done above, otherwise you run the risk of returning inconsistent values
for Equals & GetHashCode which will cause even more confusion (for the
dictionary & you).

Hope this helps
Jay
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top