Dictionary Class and ContainsKey Comparison

Joined
Mar 26, 2009
Messages
15
Programming Experience
Beginner
Hi,

When using the Dictionary class when the key and value types are your own custom types, is it possible to specify the property of the key type object to use with the ContainsKey method? Best described with an example:

VB.NET:
Dim dict as New Dictionary(Of CutsomType, AnotheCustomType)

Dim obj1 as CustomType ' Custom type with 3 properties ID, LastName and FirstName
Dim obj2 as AnotherCustomType

obj1 = New Customtype(1, "Smith", "John")
obj2 = New AnotherCustomType("a", "b")

If not dict.ContainsKey(obj1) Then
    dict.Add(obj1, obj2)
End If

' obj2 with key obj1 added successfully as no object of type CustomType with ID equal to 1 exists

obj1 = New Customtype(2, "Jones", "Alan")
obj2 = New AnotherCustomType("d", "e")

If not dict.ContainsKey(obj1) Then
    dict.Add(obj1, obj2)
End If

' obj2 with key obj1 added successfully as no object of type CustomType with ID equal to 1 exists

obj1 = New Customtype(1, "Bloggs", "Joe")
obj2 = New AnotherCustomType("f", "g")

If not dict.ContainsKey(obj1) Then
    dict.Add(obj1, obj2)
End If

' obj2 with key obj1 NOT added as an object of type CustomType with ID equal to 1 exists

I could just omit the lines with ContainsKey but I'd prefer to know how it's making the comparison and how to change it if required. I don't want to use an integer containing the ID for the key type because I want to reference the whole object later on again.

Thanks,

Norman
 
Here's an example where I've overwritten Equals and GetHashCode. In the example I'm comparing all 3 of the properties in TestClass but you can just check the ID if that's all you're interested in.

VB.NET:
Public Class TestClass

	Public Sub New()

	End Sub

	Public Sub New(ByVal identity As Integer, ByVal first As String, ByVal last As String)
		ID = identity
		FirstName = first
		LastName = last
	End Sub

	Private _ID As Integer
	Public Property ID() As Integer
		Get
			Return _ID
		End Get
		Set(ByVal value As Integer)
			_ID = value
		End Set
	End Property

	Private _FirstName As String
	Public Property FirstName() As String
		Get
			Return _FirstName
		End Get
		Set(ByVal value As String)
			_FirstName = value
		End Set
	End Property

	Private _LastName As String
	Public Property LastName() As String
		Get
			Return _LastName
		End Get
		Set(ByVal value As String)
			_LastName = value
		End Set
	End Property

	Public Overrides Function Equals(ByVal obj As Object) As Boolean
		Dim comparedObj As TestClass = TryCast(obj, TestClass)

		If comparedObj Is Nothing Then
			Return False
		End If

		Return (comparedObj.ID = ID) And (comparedObj.FirstName = FirstName) And (comparedObj.LastName = LastName)

	End Function

	Public Overrides Function GetHashCode() As Integer
		Return ID.GetHashCode Xor FirstName.GetHashCode Xor LastName.GetHashCode
	End Function

End Class

VB.NET:
Public Class Form1

	Dim dict As New Dictionary(Of TestClass, Integer)

	Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) _
	Handles MyBase.Load

		Dim item As TestClass

		item = New TestClass(1, "Joe", "Blow")

		If Not dict.ContainsKey(item) Then
			dict.Add(item, 1)
		Else
			MessageBox.Show("Item already exists")
		End If

		item = New TestClass(2, "Bob", "Smith")

		If Not dict.ContainsKey(item) Then
			dict.Add(item, 2)
		Else
			MessageBox.Show("Item already exists")
		End If

		item = New TestClass(1, "Joe", "Blow")

		If Not dict.ContainsKey(item) Then
			dict.Add(item, 3)
		Else
			MessageBox.Show("Item already exists")
		End If

	End Sub
End Class
 
Back
Top