我厌倦了为我所拥有的各种代码做这样的代码块:
if (dict.ContainsKey[key]) {
dict[key] = value;
}
else {
dict.Add(key,value);
}
和查找(即键 - >值列表)
if (lookup.ContainsKey[key]) {
lookup[key].Add(value);
}
else {
lookup.Add(new List<valuetype>);
lookup[key].Add(value);
}
我是否应该使用另一个集合库或扩展方法在一行代码中执行此操作,无论键和值类型是什么?
e.g。
dict.AddOrUpdate(key,value)
lookup.AddOrUpdate(key,value)
答案 0 :(得分:34)
正如Evgeny所说,索引器已经取代现有的值 - 所以如果只是想要无条件地设置给定键的值,你可以做
dictionary[key] = value;
更有趣的案例是“获取一个值,或者在必要时插入它”。使用扩展方法很容易:
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
TValue value)
{
return dictionary.GetOrCreateValue(key, () => value);
}
public static TValue GetOrCreateValue<TKey, TValue>
(this IDictionary<TKey, TValue> dictionary,
TKey key,
Func<TValue> valueProvider)
{
TValue ret;
if (!dictionary.TryGetValue(key, out ret))
{
ret = valueProvider();
dictionary[key] = ret;
}
return ret;
}
注意使用委托创建默认值 - 这有助于像“list as value”这样的场景;你不想创建空列表,除非你必须:
dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
另请注意,如果密钥已经存在,这只会执行一次查找 - 无需执行ContainsKey
和然后查找值。在创建新值时,它仍然需要两次查找。
答案 1 :(得分:14)
更新时,您无需执行检查。只需使用:
dict[key] = value
它将取代任何现有价值。遗憾的是,在检索值时,没有方便的单一方法(如Python中的setdefault
),但您可以创建自己的扩展方法。像这样:
if (!lookup.TryGetValue(key, out value))
{
value = new List<T>();
lookup.Add(key, value);
}
答案 2 :(得分:4)
.NET 4.0中的ConcurrentDictionary有this nice method。您也可以为此编写扩展方法。
答案 3 :(得分:3)
如果使用.NET Framework 4或更高版本,则可以使用AddOrUpdate Method
dict.AddOrUpdate(key,value)
添加或更新就像这样
dict[key] = value;
答案 4 :(得分:1)
我不确定是否有一个像你要求的方法,但是你可以为它编写一个小函数,或者使用try catch异常,大概如果你尝试添加一个已存在的值,它将抛出一个异常。如果你抓住它并忽略它......只是一个建议
答案 5 :(得分:0)
我喜欢的AddOrUpdate方法,但我也喜欢字典集合的表现:)所以,这是实现ConcurrentDictionary的所有类的扩展方法。
public static TValue AddOrUpdate<TKey, TValue>(
this IDictionary<TKey, TValue> dict,
TKey key,
TValue addValue,
Func<TKey, TValue, TValue> updateValueFactory)
{
TValue existing;
if (dict.TryGetValue(key, out existing))
{
addValue = updateValueFactory(key, existing);
dict[key] = addValue;
}
else
{
dict.Add(key, addValue);
}
return addValue;
}
public static TValue AddOrUpdate<TKey, TValue>(
this IDictionary<TKey, TValue> dict,
TKey key,
Func<TKey, TValue> addValueFactory,
Func<TKey, TValue, TValue> updateValueFactory)
{
TValue existing;
if (dict.TryGetValue(key, out existing))
{
existing = updateValueFactory(key, existing);
dict[key] = existing;
}
else
{
existing = addValueFactory(key);
dict.Add(key, existing);
}
return existing;
}