Let's say I have a method as follows:
internal MyClass GetValue(long key)
{
if (_myDictionary.ContainsKey(key))
return _myDictionary[key];
return null; // Not found
}
IDictionary<long,MyClass> _myDictionary=...
But the above code has two lookups in the dictionary:
Is there a more optimal way to phrase such a function, so that only one lookup is performed, but the case of "not found" is still handled via a null return (i.e., not via a not found exception)?
For example, it would have been nice if the lookup for the key returned some sort of iterator that could be used to retrieve the value or an invalid iterator if the value was not found as is done in C++. Perhaps C# has a better way of doing this given its language features.
The TryGetValue
method was designed for precisely this scenario - to avoid the two lookup operations.
This method combines the functionality of the ContainsKey method and the Item property.
If the key is not found, then the value parameter gets the appropriate default value for the value type TValue.
[...] Use the TryGetValue method if your code frequently attempts to access keys that are not in the dictionary. Using this method is more efficient than catching the KeyNotFoundException thrown by the Item property.
internal MyClass GetValue(long key)
{
MyClass maybeValue;
// Normally, one would inspect the return value of this method
// but in this case, it's not necessary since a failed lookup
// will set the out argument to default(valType), which is null
// for a reference type - exactly what you want.
_myDictionary.TryGetValue(key, out maybeValue);
return maybeValue;
}
typing up SPFiredrakes idea ...
public static class Extensions
{
public static TValue GetValueOrDefault<TKey, TValue>(
this IDictionary<Tkey, TValue> iDictionary, Tkey key)
{
TValue result;
return iDictionary.TryGetValue(key, out result) ? result : default(TValue)
}
}
used like this
var d = new Dictionary<long, SomeType>
{{1, new SomeType()}, {42, new SomeType()}, ...}
var value1 = d.GetValueOrDefault(1);
var value42 = d.GetValueOrDefault(42);
var valueX = d.GetValueOrDefault(10);
Of course, you should now check to see if your values are null
, which may be why the .Net team omitted this feature.
You should use TryGetValue
instead - it uses a single lookup.
internal MyClass GetValue(long key) {
MyClass res = null;
_myDictionary.TryGetValue(key, out res)
return res;
}
The call is short enough to use "inline", without adding a wrapper function. TryGetValue
returns a bool
indicating if the lookup has been successful or not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With