views:

915

answers:

7

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.

+13  A: 

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
You could even have an overload that returned a 'default' T ;).
meandmycode
This is a nice use of extension methods... I've often done similar things when using lists/collections/enumerations (LINQ to XML in particular).
Noldorin
+11  A: 
Object value;
if(dict.TryGetValue("nonexistent key", out value))
{
    // this only works when key is found..
}
// no exception is thrown here..
Akash Kava
ive never seen "out" used before what does that do?
Crash893
@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
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
+1  A: 

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

Wedge
Why would performance be an issue? ContainsKey is an O(1) operation.
Juliet
If you need to return the value then you need to retrieve it from the Dictionary as well.
Wedge
A: 
    string Q = "nonexistent key";
    string A = "";


    if(dict.containskey(Q))
    {
        A= dict[Q];
    }
    else
    {
       //handler code here
    }
Crash893
A: 
if(myDictionary.ContainsKey("TestKey") 
{       
  System.Print(myDictionary["TestKey"]); 
}
Carra
A: 
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;}
    }

}

acidzombie24
+2  A: 

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

Sean
Thanks i didnt know this :) +1
acidzombie24