4

I have a dictionary that I want to access with a key that is the combination of a string (AcctNum) and a date (BalDate).

It seems to me the simplest approach is to create the key by simply converting the date to a string and concatenating:

MyKey = BalDate.ToString & "|" & AcctNum

I know I also have the option of creating a composite key by writing a separate class and overriding GetHashCode() and Equals() a la this solution.

To me, the concatenated string is a simpler, if somewhat less elegant, solution. Am I missing some compelling reason why I should go with the composite key class approach?

This lookup is the crux of the project I am working on, so performance is my main objective (with readability a close second).

Community
  • 1
  • 1
mwolfe02
  • 23,787
  • 9
  • 91
  • 161

3 Answers3

2

Use a Tuple as key for your dictionary.

MyKey = Tuple.Create(BalDate, AcctNum)

Tuples are simpler and less error-prone than concatenating strings. It is better than using a separate class, since you don't need to override GetHashCode() and Equals() yourself.

Eldritch Conundrum
  • 8,452
  • 6
  • 42
  • 50
2

If performance is most important to you, then using a separate object is likely to be a better solution: you will save on formatting a date as a string every time you are preparing a lookup key. In addition, having a multipart key is easier to extend, should you decide to add more parts to the key: it is much easier to overlook a missing element of a concatenation than a missing parameter of a constructor.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
1

You could also create a specialized collection by inheriting from Dictionary(Of TKey, TValue)

Public Class BalanceDict
    Inherits Dictionary(Of String, Balance)

    Public Shadows Sub Add(ByVal bal As Balance)
        MyBase.Add(bal.BalDate & "|" & bal.AcctNum, bal)
    End Sub

    Public Shadows Function TryGetValue(ByVal balDate As Date, ByVal acctNum As String, <OutAttribute()> ByRef bal As Balance) As Boolean
        Return MyBase.TryGetValue(balDate & "|" & acctNum, bal)
    End Function
End Class

I do not think that the difference in speed between a composite key and a concatenated string is substantial. With a composite key, you do not have to convert the date to a string; however, you will have to calculate different hash codes and to combine them. By using a specialized implementation of a dictionary, however, you can hide these implementation details and at any time decide to change the way you generate the keys without affecting other parts of your program.

Olivier Jacot-Descombes
  • 104,806
  • 13
  • 138
  • 188