DynamicDictionary, C# style
20 May 2009
in the early afternoon
Matt Winckler
A couple of years ago I posted my DynamicDictionary class, intended to act as a multidimensional hashtable that won’t throw exceptions the way a Dictionary<T> will when attempting to access a null bucket.
Since then I’ve experienced the supremely pleasant circumstance of changing my primary language from VB.NET to C#. Although I haven’t used the DynamicDictionary much lately, there have been a couple of times when I’ve wanted it but wasn’t at the computer on which I translated it from VB.NET to C#, resulting in annoyance at having to re-translate (or just skip it entirely). Thus, I’m posting the C# version now, primarily for my own benefit and archival. Read the original post for an explanation of functionality/usage.
(Also: I know I need a better way to present code here. A theme rewrite and major cleanup/recategorization for this blog is on my todo list for later this year. I may also split out the technical/non-technical content into separate RSS feeds so the theologians and other non-developer friends don’t have to wade through all these cryptic and baffling series of semicolons and brackets, which, pathetic though it seems, does in fact constitute my daily working life. Until then, grit your teeth!)
public class DynamicDictionary<K, V> : Dictionary<K, V> where V : new() {
public DynamicDictionary() { }
/// <summary>
/// Retrieves the value associated with the specified key.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>If found in the dictionary, returns the value associated with <c>key</c>.
/// If no such value exists, creates and returns a new <c>V</c>.</returns>
public new V this[K key] {
get {
V val;
if (!this.TryGetValue(key, out val)) {
val = new V();
base.Add(key, val);
}
return val;
}
set {
base[key] = value;
}
}
/// <summary>
/// Retrieves the value associated with the specified key. If <c>autoCreateItem</c>
/// is true and no value exists, creates a new <c>V</c>, stores it in bucket <c>key</c>,
/// and returns it. Otherwise, returns the default value for <c>V</c> (without storing
/// it in the dictionary).
/// </summary>
/// <param name="key">The key.</param>
/// <param name="autoCreateItem">Specifies whether or not a new item should be created and
/// added to the dictionary if a value does not already exist. True == if value does not exist,
/// a new <c>V</c> will be created, added to the dictionary, and returned. False == if value
/// does not exist, nothing will be added to the dictionary and <c>default(V)</c> will be returned.</param>
/// <returns>The value found in bucket <c>key</c>, or if no value exists, either a new <c>V</c>
/// or <c>default(V)</c> (based on value specified in <c>autoCreateItem</c>).</returns>
public V this[K key, bool autoCreateItem] {
get {
V val = default(V);
if (!base.TryGetValue(key, out val)) {
if (autoCreateItem) {
val = new V();
base.Add(key, val);
}
}
return val;
}
set {
base[key] = value;
}
}
}
