在一些遗留代码中,我看到了以下扩展方法,以方便添加一个新的键-值项或更新值,如果键已经存在。
方法-1(遗留代码)。
public static void CreateNewOrUpdateExisting<TKey, TValue>(
this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
if (map.ContainsKey(key))
{
map[key] = value;
}
else
{
map.Add(key, value);
}
}
不过,我已经检查了map[key]=value做完全相同的工作。也就是说,这个方法可以替换为下面的method -2。
方法2。
public static void CreateNewOrUpdateExisting<TKey, TValue>(
this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
map[key] = value;
}
现在,我的问题是…如果我把Method-1换成Method-2会有问题吗?它会在任何可能的情况下断裂吗?
另外,我认为这曾经是哈希表和字典之间的区别。HashTable允许更新项目,或使用索引器添加新项目,而Dictionary不允许!!这个差异在c# > 3.0版本中被消除了吗?
该方法的目的是如果用户再次发送相同的键值,该方法只需用新值更新条目,如果新的键值对已经发送给该方法,则创建一个新的条目。
方法2更好:
更少的代码
完全相同(除了一些不可能的边缘情况)
快
下面是一个基准示例,用于演示方法2的性能优势。
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Running;
public class Program
{
public static void Main()
{
BenchmarkRunner.Run<DictionaryBenchmarks>();
}
}
[MemoryDiagnoser]
public class DictionaryBenchmarks
{
private readonly IDictionary<int, bool> _map = new Dictionary<int, bool>();
private readonly int[] _arr = new int[20]
{
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19
};
[Benchmark]
public void CreateNewOrUpdateExistingWithContainsKeyCheck()
{
foreach (int item in _arr)
{
if (_map.ContainsKey(item))
{
_map[item] = true;
}
else
{
_map.Add(item, true);
}
}
}
[Benchmark]
public void CreateNewOrUpdateExistingWithoutContainsKeyCheck()
{
foreach (int item in _arr)
{
_map[item] = true;
}
}
}
Method |
Mean |
Error |
StdDev |
Allocated |
CreateNewOrUpdateExistingWithContainsKeyCheck |
232.0 ns |
4.19 ns |
10.52 ns |
- |
CreateNewOrUpdateExistingWithoutContainsKeyCheck |
131.9 ns |
2.12 ns |
4.83 ns |
- |
我知道它不是字典<TKey, TValue>类,但是你可以避免KeyNotFoundException而增加一个值,如:
dictionary[key]++; // throws `KeyNotFoundException` if there is no such key
通过使用ConcurrentDictionary<TKey, TValue>及其非常好的方法AddOrUpdate()..
让我举个例子:
var str = "Hellooo!!!";
var characters = new ConcurrentDictionary<char, int>();
foreach (var ch in str)
characters.AddOrUpdate(ch, 1, (k, v) => v + 1);