C# .net字典和查找添加/更新

C# .net字典和查找添加/更新,c#,collections,C#,Collections,我厌倦了对我拥有的各种代码位执行这样的代码块: if (dict.ContainsKey[key]) { dict[key] = value; } else { dict.Add(key,value); } 和用于查找(即键->值列表) 我不确定是否有你要求的方法,但是你可以为它编写一个小函数,或者使用try-catch异常,如果你尝试添加一个已经存在的值,它可能会抛出一个异常。如果你抓住了它而忽略了它。。。只是.NET4.0中ConcurrentDicti

我厌倦了对我拥有的各种代码位执行这样的代码块:

if (dict.ContainsKey[key]) {  
    dict[key] = value;  
}  
else {  
    dict.Add(key,value);  
}
和用于查找(即键->值列表)


我不确定是否有你要求的方法,但是你可以为它编写一个小函数,或者使用try-catch异常,如果你尝试添加一个已经存在的值,它可能会抛出一个异常。如果你抓住了它而忽略了它。。。只是.NET4.0中ConcurrentDictionary的一个建议。您也可以为此编写扩展方法。

更新时,您不需要执行检查。只需使用:

dict[key] = value
它将替换任何现有值。不幸的是,在检索值时,没有方便的单一方法(如Python中的
setdefault
),但您可以创建自己的扩展方法。大概是这样的:

if (!lookup.TryGetValue(key, out value))
{
     value = new List<T>();
     lookup.Add(key, value);
}
if(!lookup.TryGetValue(键,输出值))
{
值=新列表();
查找。添加(键、值);
}

正如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;
}
公共静态TValue GetOrCreateValue
(这本词典,
TKey键,
t价值(价值)
{
返回dictionary.GetOrCreateValue(键,()=>value);
}
公共静态TValue GetOrCreateValue
(这本词典,
TKey键,
Func值提供程序)
{
TValue-ret;
if(!dictionary.TryGetValue(key,out-ret))
{
ret=valueProvider();
字典[键]=ret;
}
返回ret;
}
注意使用委托来创建默认值,这有助于实现“列表为值”这样的场景;您不想创建空列表,除非您必须:

dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
dict.GetOrCreateValue(键,()=>newlist())。添加(项);

还要注意的是,如果键已经存在,这只执行一次查找-不需要执行
ContainsKey
然后查找值。但是,在创建新值时,它仍然需要两次查找。

如果使用.NET Framework 4或更高版本,您可以使用

添加或更新是这样的

dict[key] = value;
我喜欢的方法,但我也喜欢字典集合的性能:)所以,这是所有实现类的扩展方法

publicstatictvalue AddOrUpdate(
这是我的字典,
TKey键,
TValue附加值,
Func更新值(工厂)
{
价值存在;
if(dict.TryGetValue(键,不存在))
{
addValue=updateValueFactory(键,现有);
dict[key]=addValue;
}
其他的
{
dict.Add(key,addValue);
}
返回附加值;
}
公共静态TValue AddOrUpdate(
这是我的字典,
TKey键,
Func addValueFactory,
Func更新值(工厂)
{
价值存在;
if(dict.TryGetValue(键,不存在))
{
现有=updateValueFactory(键,现有);
dict[key]=现有;
}
其他的
{
现有=addValueFactory(键);
dict.Add(键,现有);
}
返回现有的;
}

这仅适用于
ConcurrentDictionary
是的,您可以将其与Concurrent Dictionary一起使用,因为您不想陷入这样的陷阱:检查添加条件,确定需要执行添加,然后让其他人在背后执行添加。我相信AddOrUpdate使它原子化了。
lookup
ILookup
?我这么想不是因为它不应该有
ContainsKey
方法。仅确认.NET并没有更改自问题提出以来的查找,因为它正在寻找更新
ILookup
的方法。。。
dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
dict.AddOrUpdate(key,value)  
dict[key] = value;
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;
}