用于查找的C#最佳IDictionary用法,可能未找到

时间:2012-02-28 15:55:34

标签: c# .net c#-4.0 .net-4.0

假设我有一个方法如下:

internal MyClass GetValue(long key)
{
  if (_myDictionary.ContainsKey(key))
    return _myDictionary[key];

  return null; // Not found
}

IDictionary<long,MyClass> _myDictionary=...

但是上面的代码在字典中有两个查找:

  1. 关键存在的测试
  2. 实际检索值
  3. 是否有一种更优化的方式来表达这样的函数,因此只执行一次查找,但“未找到”的情况仍然通过空返回处理(即,不通过未找到的异常)?

    例如,如果对键的查找返回某种可用于检索值的迭代器或者如果未在C ++中找到该值而找到无效迭代器,则会很好。考虑到语言特性,C#可能有更好的方法。

3 个答案:

答案 0 :(得分:16)

TryGetValue方法专为这种情况而设计 - 避免两次查找操作。

  

此方法结合了ContainsKey方法的功能   Item属性。

     

如果未找到密钥,则value参数将获得相应的参数   值类型TValue的默认值。

     

[...]如果您的代码经常尝试访问,请使用TryGetValue方法   不在字典中的键。使用这种方法更多   比捕获Item抛出的KeyNotFoundException更有效   属性。

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; 
}

答案 1 :(得分:2)

输入SPFiredrakes的想法...

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)
    }
}

像这样使用

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);

当然,您现在应检查您的值是否为null,这可能是.Net团队省略此功能的原因。

答案 2 :(得分:1)

您应该使用TryGetValue - 它使用单个查找。

internal MyClass GetValue(long key) {
    MyClass  res = null;
    _myDictionary.TryGetValue(key, out res)
    return res;
}

调用足够短,可以使用“内联”,而无需添加包装函数。 TryGetValue返回bool,表示查找是否成功。