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

时间:2011-05-20 03:52:39

标签: c# .net vb.net generics dictionary

如果我希望将项目放入System.Collections.Generic.Dictionary,我可以Add或设置Item

我知道如果我们Add它会检查密钥是否已经存在,如果不存在则会抛出异常。

因此,在添加大量项目时,我是否应该更喜欢设置Item而不是Add,因为Add会执行不必​​要的检查,这可能会让事情变慢?

3 个答案:

答案 0 :(得分:35)

以下是设置项目时发生的事情:

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

最后一个参数last bool add参数只会影响这一行:

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

因此,如果您在添加重复项时需要例外,则需要使用“添加”。如果要覆盖现有项目,则需要设置项目。

答案 1 :(得分:3)

这一切都取决于您是要处理重复键还是覆盖任何可能存在的项。要检查重复项,您可以使用:

例如:

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

答案 2 :(得分:2)

抛出异常是便宜的,它处理它们是昂贵的。 try / catch块的try部分运行正常。当执行catch块时,它必须展开堆栈以填充堆栈跟踪(以及其他内容)。这使得例外变得昂贵。如果您有办法通过使用Dictionary<T>.ContainsKey

等方法来避免捕获异常,这就是这个原因

您不太可能注意到调用Add和设置Item之间的性能差异。因此,请使用最适合该情况的那个。

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