C# 检索字典值最佳实践

C# 检索字典值最佳实践,c#,.net,dictionary,C#,.net,Dictionary,我最近注意到Dictionary.TryGetValue(TKey,out TValue),我很好奇从字典中检索值的更好方法是什么 我一直在做: if (myDict.Contains(someKey)) someVal = myDict[someKey]; ... 除非我知道它一定在里面 这样做是否更好: if (myDict.TryGetValue(somekey, out someVal) ... 哪种做法更好?一个比另一个快吗?我可以想象,Try版本会更慢

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

我一直在做:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
     ...
除非我知道它一定在里面

这样做是否更好:

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

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

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

要快多少?这取决于天气 手头的数据集。当你打电话给 包含方法,字典执行 内部搜索以查找其索引。如果 它返回真值,你需要另一个 索引搜索以获取实际值。 使用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;
}
康纳斯基是这样的:

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

我认为trygetvalue做的事情更像:

if(myDict.ReallyOptimisedVersionofContains(someKey))
{ 
  someVal = myDict[someKey];
  return true;
}
return false;
因此,希望没有尝试/捕获任何地方


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

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

编辑:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
myDict.TryGetValue(somekey, out someVal)
好的,我理解你的困惑,所以让我详细说明一下:

案例1:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
myDict.TryGetValue(somekey, out someVal)
在本例中,有两个对FindEntry的调用,一个用于检查密钥是否存在,另一个用于检索密钥

案例2:

if (myDict.Contains(someKey))
     someVal = myDict[someKey];
myDict.TryGetValue(somekey, out someVal)
在这种情况下,只有一个对FindKey的调用,因为结果索引是为同一方法中的实际检索而保留的

    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


还可以尝试检查这个类似的问题:

TryGetValue稍微快一点,因为FindEntry只会被调用一次。TryGetValue在拥有大型词典时要快得多理论上(实际上也是如此),这不应该取决于词典的大小,因为预期的(!)检索时间是恒定的,即,与字典大小无关!同意。TryGetValue无需执行两次键查找。它还可以在多线程的情况下提供帮助。在检查该值是否存在的时间间隔内,该值可能已被添加或删除。这可能导致“密钥已存在”或“未找到密钥”异常。