简体   繁体   English

检索字典值最佳实践

[英]Retrieving Dictionary Value Best Practices

I just recently noticed Dictionary.TryGetValue(TKey key, out TValue value) and was curious as to which is the better approach to retrieving a value from the Dictionary.我最近才注意到Dictionary.TryGetValue(TKey key, out TValue value)并且很好奇从字典中检索值的更好方法是什么。

I've traditionally done:我传统上做过:

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

unless I know it has to be in there.除非我知道那一定是在那里。

Is it better to just do:是否更好地执行以下操作:

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

Which is the better practice?哪个是更好的做法? Is one faster than the other?一个比另一个快吗? I would imagine that the Try version would be slower as its 'swallowing' a try/catch inside itself and using that as logic, no?我会想象 Try 版本会更慢,因为它会“吞下”自身内部的 try/catch 并将其用作逻辑,不是吗?

TryGetValue is slightly faster, because FindEntry will only be called once. TryGetValue 稍微快一点,因为 FindEntry 只会被调用一次。

How much faster?快多少? It depends on the dataset at hand.这取决于手头的数据集。 When you call the Contains method, Dictionary does an internal search to find its index.当您调用 Contains 方法时,Dictionary 会进行内部搜索以查找其索引。 If it returns true, you need another index search to get the actual value.如果它返回 true,则需要另一个索引搜索来获取实际值。 When you use TryGetValue, it searches only once for the index and if found, it assigns the value to your variable.当您使用 TryGetValue 时,它​​只搜索索引一次,如果找到,它会将值分配给您的变量。

FYI: It's not actually catching an error.仅供参考:实际上并没有发现错误。

It's calling:它在呼唤:

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 is this:包含密钥是这样的:

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

Well in fact TryGetValue is faster.事实上,TryGetValue 更快。 How much faster?快多少? It depends on the dataset at hand.这取决于手头的数据集。 When you call the Contains method, Dictionary does an internal search to find its index.当您调用 Contains 方法时,Dictionary 会进行内部搜索以查找其索引。 If it returns true, you need another index search to get the actual value.如果它返回 true,则需要另一个索引搜索来获取实际值。 When you use TryGetValue, it searches only once for the index and if found, it assigns the value to your variable.当您使用 TryGetValue 时,它​​只搜索索引一次,如果找到,它会将值分配给您的变量。

Edit:编辑:

Ok, I understand your confusion so let me elaborate:好的,我理解你的困惑,所以让我详细说明:

Case 1:案例1:

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

In this case there are 2 calls to FindEntry, one to check if the key exists and one to retrieve it在这种情况下,有 2 次调用 FindEntry,一次是检查密钥是否存在,另一次是检索它

Case 2:案例2:

myDict.TryGetValue(somekey, out someVal)

In this case there is only one call to FindKey because the resulting index is kept for the actual retrieval in the same method.在这种情况下,只有一次对 FindKey 的调用,因为在同一方法中为实际检索保留了结果索引。

I imagine that trygetvalue is doing something more like:我想 trygetvalue 正在做的事情更像是:

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

So hopefully no try/catch anywhere.所以希望不要在任何地方尝试/捕获。

I think it is just a method of convenience really.我认为这真的只是一种方便的方法。 I generally use it as it saves a line of code or two.我通常使用它,因为它可以节省一两行代码。

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

Like you can see TryGetValue is same as ContainsKey + one array lookup.就像您可以看到 TryGetValue 与 ContainsKey + 一个数组查找相同。

If your logic is only to check if the key is existing in the Dictionary and nothing else related to this key (taking the value for the key) you should use ContainsKey.如果您的逻辑只是检查键是否存在于字典中,而没有其他与此键相关的内容(取键值),则应使用 ContainsKey。

Try also checking this similar question: is-there-a-reason-why-one-should-use-containskey-over-trygetvalue还尝试检查这个类似的问题: is-there-a-reason-why-one-should-use-containskey-over-trygetvalue

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM