在某些遗留代码中,我看到了以下扩展方法,以便于添加新的键值项或更新值(如果该键已存在)。
方法-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
完成了同样的工作。也就是说,此方法可以替换为下面的方法-2。
方法-2。
public static void CreateNewOrUpdateExisting<TKey, TValue>(
this IDictionary<TKey, TValue> map, TKey key, TValue value)
{
map[key] = value;
}
现在,我的问题是..如果我用Method-2替换Method-1会有什么问题吗?它会在任何可能的情况下破裂吗?
另外,我认为这曾经是HashTable和Dictionary之间的区别。 HashTable允许更新项目,或使用索引器添加新项目,而词典则不行!在C#&gt;中消除了这种差异吗? 3.0版本?
如果用户再次发送相同的键值,则此方法的目标不是抛出异常,该方法应该只使用新值更新条目,并且如果已发送新的键值对则创建新条目方法。
答案 0 :(得分:195)
如果我用Method-2替换Method-1会有什么问题吗?
不,只需使用map[key] = value
即可。这两个选项是等效的。
关于Dictionary<>
与Hashtable
:当您启动Reflector时,您会看到两个类的索引器设置器都调用this.Insert(key, value, add: false);
而add
参数负责抛出插入重复键时的异常。所以两个类的行为都是一样的。
答案 1 :(得分:37)
没问题。我甚至会从源代码中删除CreateNewOrUpdateExisting
并在代码中直接使用map[key] = value
,因为这样更易读,因为开发人员通常会知道map[key] = value
的含义。
答案 2 :(得分:17)
旧问题,但我觉得我应该添加以下内容,甚至更多,因为.net 4.0在问题写入时已经启动了。
从.net 4.0开始,存在名称空间System.Collections.Concurrent
,其中包含线程安全的集合。
集合System.Collections.Concurrent.ConcurrentDictionary<>
完全符合您的要求。它具有AddOrUpdate()
方法,并具有线程安全的附加优势。
如果您处于高性能场景而不处理多个线程,则map[key] = value
已经给出的答案会更快。
在大多数情况下,此性能优势无关紧要。如果是这样,我建议使用ConcurrentDictionary,因为:
答案 3 :(得分:6)
从功能上讲,它们是等价的。
性能方面map[key] = value
会更快,因为您只进行单次查找而不是两次。
风格方面,越短越好:)
在大多数情况下,代码似乎在多线程上下文中工作正常。但是,如果没有额外的同步,不线程安全。
答案 4 :(得分:1)
唯一的问题可能是有一天
map [key] =值
将转换为-
map [key] ++;
这将导致KeyNotFoundException。
答案 5 :(得分:0)
我知道它不是Dictionary<TKey, TValue>
类,但是您可以在增加像这样的值时避免使用KeyNotFoundException
:
dictionary[key]++; // throws `KeyNotFoundException` if there is no such key
通过使用ConcurrentDictionary<TKey, TValue> and its really nice method AddOrUpdate().。
让我展示一个例子:
var str = "Hellooo!!!";
var characters = new ConcurrentDictionary<char, int>();
foreach (var ch in str)
characters.AddOrUpdate(ch, 1, (k, v) => v + 1);