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

fre*_*ith 33 c# collections

对于我所拥有的各种代码,我厌倦了这样的代码块:

if (dict.ContainsKey[key]) {  
    dict[key] = value;  
}  
else {  
    dict.Add(key,value);  
}
Run Code Online (Sandbox Code Playgroud)

和查找(即键 - >值列表)

if (lookup.ContainsKey[key]) {  
    lookup[key].Add(value);  
}  
else {  
    lookup.Add(new List<valuetype>);  
    lookup[key].Add(value);  
}  
Run Code Online (Sandbox Code Playgroud)

是否存在另一个集合库或扩展方法,无论键和值类型是什么,我都应该在一行代码中执行此操作?

例如

dict.AddOrUpdate(key,value)  
lookup.AddOrUpdate(key,value)
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 35

正如Evgeny所说,索引器已经取代了现有的值 - 所以如果你只是想无条件地设置给定键的值,你可以做

dictionary[key] = value;
Run Code Online (Sandbox Code Playgroud)

更有趣的情况是"获取一个值,或者在必要时插入它".使用扩展方法很容易:

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;
}
Run Code Online (Sandbox Code Playgroud)

注意使用委托来创建默认值 - 这有助于像"list as value"这样的场景; 你不想创建空列表,除非你必须:

dict.GetOrCreateValue(key, () => new List<int>()).Add(item);
Run Code Online (Sandbox Code Playgroud)

同样要注意,如果关键是已经存在这个仅执行查找一次-有没有必要做一个ContainsKey然后查找值.但是在创建新值时仍需要两次查找.


EMP*_*EMP 14

更新时,您无需执行检查.只需使用:

dict[key] = value
Run Code Online (Sandbox Code Playgroud)

它将取代任何现有价值.遗憾的是,在检索值时,没有方便的单一方法(如setdefaultPython中),但您可以创建自己的扩展方法.像这样的东西:

if (!lookup.TryGetValue(key, out value))
{
     value = new List<T>();
     lookup.Add(key, value);
}
Run Code Online (Sandbox Code Playgroud)