HiveBrain v1.2.0
Get Started
← Back to all entries
patternMinor

KeyValuePair implementation

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
implementationkeyvaluepairstackoverflow

Problem

In order to implement my own Dictionary in VB6, I've implemented a KeyValuePair class, which can accomodate any type as its key, or value.

This KeyValuePair class implements the IComparable and IEquatable interfaces which I'm also using in this custom List implementation

KeyValuePair.cls
`Private Type tKeyValuePair
Key As Variant
value As Variant
End Type

Private this As tKeyValuePair
Implements IComparable
Implements IEquatable
Option Explicit

Private Function IsComparable() As Boolean
IsComparable = Not IsObject(this.Key) Or TypeOf this.Key Is IComparable
End Function

Public Property Get Key() As Variant
If IsObject(this.Key) Then
Set Key = this.Key
Else
Key = this.Key
End If
End Property

Public Property Let Key(k As Variant)
If IsEmpty(k) Then Err.Raise 5
this.Key = k
End Property

Public Property Set Key(k As Variant)
If IsEmpty(k) Then Err.Raise 5
Set this.Key = k
End Property

Public Property Get value() As Variant
If IsObject(this.value) Then
Set value = this.value
Else
value = this.value
End If
End Property

Public Property Let value(v As Variant)
this.value = v
End Property

Public Property Set value(v As Variant)
Set this.value = v
End Property

Public Function ToString() As String
ToString = TypeName(Me) & ""
End Function

Private Function IComparable_CompareTo(other As Variant) As Integer

Dim kvp As KeyValuePair
Set kvp = other

IComparable_CompareTo = ToString = kvp.ToString
If Not IComparable_CompareTo Then Exit Function

If IsObject(kvp.Key) Then
IComparable_CompareTo = CompareReferenceTypes(this.Key, kvp.Key)
Else
IComparable_CompareTo = CompareValueTypes(this.Key, kvp.Key)
End If

End Function

Private Function IEquatable_Equals(other As Variant) As Boolean

Dim kvp As KeyValuePair
Set kvp = other

IEquatable_Equals = ToString = kvp.ToString
If Not IEqua

Solution

That has been said before in previous reviews, there's not really a gain in having a Private Type that lets you define a Private this As tKeyValuePair, which forces you to use this. to access what would otherwise be private fields.

Actually there is one gain: doing that allows having a Key public member that encapsulates a Key private member, all without confusing poor old VB6 compiler.

Other than that, one has to see the List and possibly also the Dictionary implementation to see the benefits of the additional complexity introduced by IEquatable and IComparable interface implementations.

The code is fairly clean, straightforward and readable, breaking IEquatable and IComparable implementations into sub-functions respectively for reference and value types might be a little overboard, but it does make a nice abstraction level when one reads the implementation code.

One nitpick, the interface implementations and the corresponding sub-functions could declare a local result variable and assign the function's return value in only a single location:

Dim result As Boolean

If IsObject(kvp.Key) Then
    result = CompareReferenceTypes(this.Key, kvp.Key)
Else
    result = CompareValueTypes(this.Key, kvp.Key)
End If

IComparable_CompareTo = result


Dim result As Boolean

If IsObject(kvp.Key) Then
    result = EquateReferenceTypes(this.Key, kvp.Key)
Else
    result = EquateValueTypes(this.Key, kvp.Key)
End If

IEquatable_Equals = result


Dim result As Boolean
Dim equatable As IEquatable

If IsObject(this.Key) And TypeOf this.Key Is IEquatable Then
    Set equatable = value
    result = equatable.Equals(other)
Else
    Debug.Print "WARNING: Reference type doesn't implement IEquatable, using reference equality."
    result = (ObjPtr(value) = ObjPtr(other))
End If

EquateReferenceTypes = result


Looking more closely at the shape of the code, vertical whitespaces aren't all that consistent: there's more vertical whitespaces near the bottom of the code module, while the code near the top doesn't seem to follow the same spacing style. Minor nitpick, but for a small specialized class like this, it's an easy fix.

Code Snippets

Dim result As Boolean

If IsObject(kvp.Key) Then
    result = CompareReferenceTypes(this.Key, kvp.Key)
Else
    result = CompareValueTypes(this.Key, kvp.Key)
End If

IComparable_CompareTo = result
Dim result As Boolean

If IsObject(kvp.Key) Then
    result = EquateReferenceTypes(this.Key, kvp.Key)
Else
    result = EquateValueTypes(this.Key, kvp.Key)
End If

IEquatable_Equals = result
Dim result As Boolean
Dim equatable As IEquatable

If IsObject(this.Key) And TypeOf this.Key Is IEquatable Then
    Set equatable = value
    result = equatable.Equals(other)
Else
    Debug.Print "WARNING: Reference type doesn't implement IEquatable, using reference equality."
    result = (ObjPtr(value) = ObjPtr(other))
End If

EquateReferenceTypes = result

Context

StackExchange Code Review Q#45664, answer score: 4

Revisions (0)

No revisions yet.