C# Dictionary object – know your database structure and I won’t have to hack like this

private Dictionary theThingThatWasNotUnique(){
  blah blah blah;
  Dictionary aSetOfResults= new Dictionary();
  foreach (DataRow dr in ds.Tables[0].Rows){
    DateTime startDate= (DateTime)dr["dtStart"];
    string activityName = (string)dr["sActivityName"];
    aSetOfResults.Add(startDate, activityName);
  }
}

The Dictionary object in C# is pretty neat. It’s fast and light because it’s essentially a hash table and it really is nice to enumerate through. The gotcha is, it relies on unique values in the key. And herein lies the problem with the code above. In the application I was troubleshooting, the dates that were stored were not guaranteed to be unique. This is really a simple case of not understanding the data structure properly and making false assumptions.

Not a big deal really, because these things usually come out in the wash. The big deal is when it is only caught as the system is going live and we really need to implement a quick patch to get it working without spending a lot of time on it. I’m talking a ten minute patch so it works away for next day or so until we have time to re-factor the code properly.

Here’s what I did.

private Dictionary theThingThatWasNotUnique(){
  blah blah blah;
  Dictionary aSetOfResults= new Dictionary();
  foreach (DataRow dr in ds.Tables[0].Rows) {
    DateTime startDate= (DateTime)dr["dtStart"];
    string activityName = (string)dr["sActivityName"];
    HackUniqueDateTimeIntoDictionary(startDate, activityName , ref aSetOfResults);
    }
}
private void HackUniqueDateTimeIntoDictionary(DateTime possibleNonUniqueDateKey, string aValue, ref Dictionary theDic) {
  if (theDic.ContainsKey(possibleNonUniqueDateKey)) {
    DateTime newkey = possibleNonUniqueDateKey.AddMilliseconds(1);
    HackUniqueDateTimeIntoDictionary(newkey, aValue, ref theDic);
  } else {
    theDic.Add(possibleNonUniqueDateKey, aValue);
  }
}

It’s a bit nasty, but recursively adding a millisecond to the key if it already exists, gets me a workable solution in almost no time at all. Just as quick, you might say, is to re-factor it into an object proper or maybe an arraylist, but the various bits of code that consumed the dictionary object was complex and I didn’t have time to go through all of the various consumers and make them right.