3

When i do val = dict["nonexistent key"] i get System.Collections.Generic.KeyNotFoundException Is there a way i have my dictionary call a member function with the key as a param to generate a value?

-edit- Maybe i should of been more specific. I want to AUTOMATICALLY call a member function to do what it needs create the proper value for that key. In this case it makes an entry in my DB then gives me back its unique handle. I'll post below what my solution was.

  • I think my solution does the exact same thing. What else do you need? What exactly do you mean from _automatically_. You should somehow specify which method to call (or you can hardcode the method in my solution instead of passing it and make it pretty automatic). Otherwise, please clarify. – Mehrdad Afshari Apr 06 '09 at 10:20
  • Mehrdad: When i was posting this i was hoping i could do what my code does (http://stackoverflow.com/questions/718610/c-dictionary-missing-key/720794#720794) w/o writing an implementation (since the standard is likely to be better). I didnt like these solutions below bc i use dict[key] in many –  Apr 06 '09 at 10:24
  • places. So i would have to copy/paste it everywhere which i hate to do or call a function instead which i also dislike so i decide to emulate the lookup so i can use object naturally. i didnt know i using this technique http://stackoverflow.com/questions/718610/c-dictionary-missing-key/720827#720827 –  Apr 06 '09 at 10:26
  • Ah-ha. Got it. Yes, that's the way you should be going. – Mehrdad Afshari Apr 06 '09 at 10:46

7 Answers7

20

Use an extension method:

static class DictionaryExtensions {
   public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey,TValue> dic, TKey key, Func<TKey, TValue> valueGenerator) {
      TValue val;
      if (dic.TryGetValue(key, out val))
         return val;
      return valueGenerator(key);
   }
}

You can call it with:

dic.GetValueOrDefault("nonexistent key", key => "null");

Or pass a member function:

dic.GetValueOrDefault("nonexistent key", MyMemberFunction);
Mehrdad Afshari
  • 414,610
  • 91
  • 852
  • 789
15
Object value;
if(dict.TryGetValue("nonexistent key", out value))
{
    // this only works when key is found..
}
// no exception is thrown here..
Akash Kava
  • 39,066
  • 20
  • 121
  • 167
  • ive never seen "out" used before what does that do? – Crash893 Apr 05 '09 at 15:11
  • @Crash893: It's used to declare output parameters and to pass arguments to those parameters. http://msdn.microsoft.com/en-us/library/t3c3bfhx(VS.80).aspx – Mehrdad Afshari Apr 05 '09 at 15:28
  • 1
    out is to pass parameter as a reference, but difference between out and ref is, you do not have to initialize a variable in order to pass it as out, but if you need to pass variable as ref, you have to initialize it. – Akash Kava Apr 06 '09 at 09:45
2

Just as an aside, the technique you're talking about is called Memoization

Sean
  • 60,939
  • 11
  • 97
  • 136
1

TryGetValue() is good. You can also use ContainsKey() if you aren't performance constrained or don't need the value.

Wedge
  • 19,513
  • 7
  • 48
  • 71
1
if(myDictionary.ContainsKey("TestKey") 
{       
  System.Print(myDictionary["TestKey"]); 
}
Carra
  • 17,808
  • 7
  • 62
  • 75
0
    string Q = "nonexistent key";
    string A = "";


    if(dict.containskey(Q))
    {
        A= dict[Q];
    }
    else
    {
       //handler code here
    }
Crash893
  • 11,428
  • 21
  • 88
  • 123
0
public class MyDictionary<K, V>
{
    Dictionary<K, V> o = new Dictionary<K, V>();
    public delegate V NonExistentKey(K k);
    NonExistentKey nonExistentKey;
    public MyDictionary(NonExistentKey nonExistentKey_)
    {   o = new Dictionary<K, V>();
        nonExistentKey = nonExistentKey_;
    }

    public V this[K k]
    {
        get {
            V v;
            if (!o.TryGetValue(k, out v))
            {
                v = nonExistentKey(k);
                o[k] = v;
            }
            return v;
        }
        set {o[k] = value;}
    }

}