在字典中添加新项目或更新现有项目的方法

Posted

技术标签:

【中文标题】在字典中添加新项目或更新现有项目的方法【英文标题】:Method to Add new or update existing item in Dictionary 【发布时间】:2011-05-13 19:17:14 【问题描述】:

在一些遗留代码中,我看到了以下扩展方法,以方便添加新的键值项或更新值(如果键已存在)。

方法 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 的工作完全相同。即该方法可以替换为下面的方法二。

方法二。

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 允许更新项目,或使用索引器添加新项目,而 Dictionary 不允许!在 C# > 3.0 版本中是否消除了这种差异?

这个方法的目的是如果用户再次发送相同的key-value不会抛出异常,该方法应该只是用新的值更新条目,如果已​​经发送了新的key-value对则创建一个新的条目方法。

【问题讨论】:

【参考方案1】:

如果我将 Method-1 替换为 Method-2 会有什么问题吗?

不,只需使用map[key] = value。这两个选项是等价的。

关于Dictionary&lt;&gt;Hashtable:当你启动Reflector 时,你会看到两个类的索引器设置器都调用this.Insert(key, value, add: false); 并且add 参数负责在插入重复键时引发异常。所以这两个类的行为是相同的。

【讨论】:

【参考方案2】:

没有问题。我什至会从源代码中删除CreateNewOrUpdateExisting 并直接在您的代码中使用map[key] = value,因为这是惯用的C#; C# 开发人员通常会知道map[key] = value 表示添加或更新。

【讨论】:

【参考方案3】:

老问题,但我觉得我应该添加以下内容,甚至更多,因为在编写问题时.net 4.0 已经启动。

从 .net 4.0 开始,命名空间 System.Collections.Concurrent 包含线程安全的集合。

集合System.Collections.Concurrent.ConcurrentDictionary&lt;&gt; 完全符合您的要求。它具有AddOrUpdate() 方法以及线程安全的附加优势。

如果您处于高性能场景并且不处理多个线程,那么map[key] = value 已经给出的答案会更快。

在大多数情况下,这种性能优势是微不足道的。如果是这样,我建议使用 ConcurrentDictionary,因为:

    它在框架中 - 经过更多测试,您不是必须维护代码的人 它是可扩展的:如果你切换到多线程,你的代码已经准备好了

【讨论】:

【参考方案4】:

在功能上,它们是等价的。

性能方面map[key] = value 会更快,因为您只进行一次查找而不是两次。

风格方面,越短越好:)

在大多数情况下,代码似乎在多线程上下文中运行良好。但是,如果没有额外的同步,它是不是线程安全的。

【讨论】:

【参考方案5】:

唯一的问题可能是如果有一天

地图[键] = 值

将转变为 -

地图[键]++;

这将导致 KeyNotFoundException。

【讨论】:

【参考方案6】:

我知道它不是 Dictionary&lt;TKey, TValue&gt; 类,但是你可以避免 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);

【讨论】:

是的,看起来很不错...但是ConcurrentDictionary 为多线程(即锁)增加了很多同步开销。因此会对性能产生重大影响。

以上是关于在字典中添加新项目或更新现有项目的方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 firestore 中的现有数组中添加或删除项目?

在Python中向字典添加新项目[重复]

向现有 Xcode 项目添加尺寸类

如何在列表顶部的 recyclerview 中显示新项目(更新或添加)

C#winform添加现有项目后怎么处理

更新或添加密钥到字典 [重复]