System.Collections.Generic.Dictionary `Add` vs set `Item`

本文关键字:vs set Item Add System Generic Dictionary Collections | 更新日期: 2023-09-27 17:56:55

如果我想把项目放到System.Collections.Generic.Dictionary中,我可以Add或设置Item

我知道如果我们这样做Add它会检查密钥是否已经存在,如果不存在,它会引发异常。

因此,在添加大量项目时,我是否应该更喜欢设置Item而不是Add,因为Add进行不必要的检查实际上可能会减慢速度?

System.Collections.Generic.Dictionary `Add` vs set `Item`

以下是设置 Item 时发生的情况:

public void set_Item(TKey key, TValue value)
{
    this.Insert(key, value, false);
}

以下是添加项目时发生的情况:

public void Add(TKey key, TValue value)
{
    this.Insert(key, value, true);
}
最后一个

参数最后一个布尔值add参数只影响这一行:

if (add)
{
    ThrowHelper.ThrowArgumentException(ExceptionResource.Argument_AddingDuplicate);
}

因此,如果在添加重复项时出现异常,则需要使用"添加"。如果要覆盖现有项目,则需要设置项目。

这完全取决于您是要处理重复的键还是覆盖任何潜在的现有项目。要检查重复项,您可以使用:

  • 包含用于检查密钥是否存在的密钥方法。
  • TryGetValue 方法,用于检查键是否存在并获取值(如果可用)。

例如:

var dict = new Dictionary<int, string>();
Console.WriteLine(dict.ContainsKey(1)); // false
dict[1] = "hi";
dict[1] = "hello"; // "hi" is overwritten
// true: hello
Console.WriteLine("{0}: {1}", dict.ContainsKey(1), dict[1]);
// TryGetValue if checking by key and interested in the value
string result;
if (dict.TryGetValue(1, out result))
{
    Console.WriteLine("Key 1 exists: " + result);
}
else
{
    Console.WriteLine("Key 1 not found");
}

抛出异常很便宜,处理它们很昂贵。try/catch 块的 try 部分像正常一样运行。执行 catch 块时,它必须展开堆栈以填充堆栈跟踪(以及其他内容)。这就是使异常变得昂贵的原因。这就是避免捕获异常的原因,如果您有能力通过使用诸如Dictionary<T>.ContainsKey

您极不可能注意到调用 Add 和设置 Item 之间的性能差异。因此,请使用最适合这种情况的一种。

更新:除非代码很慢,否则不要优化代码。