【问题标题】:Retrieving Dictionary Value Best Practices检索字典值最佳实践
【发布时间】:2010-09-27 13:36:19
【问题描述】:

我最近才注意到Dictionary.TryGetValue(TKey key, out TValue value),我很好奇从字典中检索值的更好方法是什么。

我一直这样做:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...

除非我知道它必须在里面。

这样做更好吗:

if (myDict.TryGetValue(somekey, out someVal)
    ...

哪种做法更好?一个比另一个快吗?我想 Try 版本会更慢,因为它在自身内部“吞下”一个 try/catch 并将其用作逻辑,不是吗?

【问题讨论】:

    标签: c# .net dictionary


    【解决方案1】:

    TryGetValue 稍微快一些,因为 FindEntry 只会被调用一次。

    快多少?这取决于 手头的数据集。当你打电话给 包含方法,字典做一个 内部搜索以找到它的索引。如果 它返回true,你需要另一个 索引搜索以获取实际值。 当您使用 TryGetValue 时,它​​会搜索 索引只有一次,如果找到, 它将值分配给您的变量。

    仅供参考:它实际上并没有捕获错误。

    它在召唤:

    public bool TryGetValue(TKey key, out TValue value)
    {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
            value = this.entries[index].value;
            return true;
        }
        value = default(TValue);
        return false;
    }
    

    ContainsKey 是这样的:

    public bool ContainsKey(TKey key)
    {
        return (this.FindEntry(key) >= 0);
    }
    

    【讨论】:

    • TryGetValue 稍微快一些,因为 FindEntry 只会被调用一次。
    • 当你有一个大字典时,TryGetValue 会快得多
    • 理论上(好吧,实际上也是如此),这不应该取决于字典的大小,因为预期的(!)检索时间是恒定的,即与字典大小无关!
    【解决方案2】:

    其实 TryGetValue 更快。快多少?这取决于手头的数据集。当您调用 Contains 方法时,Dictionary 会进行内部搜索以查找其索引。如果它返回 true,则需要另一个索引搜索来获取实际值。当您使用 TryGetValue 时,它​​只会搜索一次索引,如果找到,它会将值分配给您的变量。

    编辑:

    好的,我理解你的困惑,所以让我详细说明:

    案例 1:

    if (myDict.Contains(someKey))
         someVal = myDict[someKey];
    

    在这种情况下,有 2 次 FindEntry 调用,一次检查密钥是否存在,一次检索它

    案例 2:

    myDict.TryGetValue(somekey, out someVal)
    

    在这种情况下,只有一次对 FindKey 的调用,因为结果索引被保留用于在同一方法中进行实际检索。

    【讨论】:

    • 同意。 TryGetValue 消除了进行两次密钥查找的需要。它也可以在多线程的情况下提供帮助。在您检查该值是否存在之间,它可能已被添加或删除。这可能会导致“密钥已存在”或“未找到密钥”异常。
    【解决方案3】:

    我想 trygetvalue 正在做的事情更像:

    if(myDict.ReallyOptimisedVersionofContains(someKey))
    { 
      someVal = myDict[someKey];
      return true;
    }
    return false;
    

    所以希望不要在任何地方尝试/捕捉。

    我认为这只是一种方便的方法。我通常使用它,因为它可以节省一两行代码。

    【讨论】:

      【解决方案4】:
          public bool TryGetValue(TKey key, out TValue value)
      {
        int index = this.FindEntry(key);
        if (index >= 0)
        {
          value = this.entries[index].value;
          return true;
        }
        value = default(TValue);
        return false;
      }
      
      public bool ContainsKey(TKey key)
      {
        return (this.FindEntry(key) >= 0);
      }
      

      如您所见,TryGetValue 与 ContainsKey + 一个数组查找相同。

      如果您的逻辑只是检查该键是否存在于字典中,并且没有其他与该键相关的内容(获取键的值),您应该使用 ContainsKey。

      也尝试检查这个类似的问题:is-there-a-reason-why-one-should-use-containskey-over-trygetvalue

      【讨论】:

        猜你喜欢
        • 2015-09-24
        • 2012-02-05
        • 1970-01-01
        • 1970-01-01
        • 2020-10-21
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        相关资源
        最近更新 更多