.NET Dictionary:获取或创建新的

我经常发现自己创建了一个带有非平凡值类(例如List )的Dictionary ,然后在填写数据时总是编写相同的代码模式。

例如:

 var dict = new Dictionary<string, List>(); string key = "foo"; string aValueForKey = "bar"; 

也就是说,我想在与"foo"键对应的列表中插入"bar" ,其中键"foo"可能不会映射到任何内容。

这是我使用不断重复的模式的地方:

 List keyValues; if (!dict.TryGetValue(key, out keyValues)) dict.Add(key, keyValues = new List()); keyValues.Add(aValueForKey); 

这样做有更优雅的方式吗?

相关问题没有这个问题的答案:

  • 是否有一个IDictionary实现,在缺少键而不是抛出时返回null?
  • 在c#字典中只查找或插入一个查找
  • 如果密钥不存在,则字典返回默认值

我们对此略有不同,但效果类似:

 public static TValue GetOrCreate(this IDictionary dict, TKey key) where TValue : new() { TValue val; if (!dict.TryGetValue(key, out val)) { val = new TValue(); dict.Add(key, val); } return val; } 

所谓的:

 var dictionary = new Dictionary>(); List numbers = dictionary.GetOrCreate("key"); 

它利用了公共无参数构造函数的generics约束: where TValue : new()

为了帮助发现,除非扩展方法非常特定于狭窄的问题,否则我们倾向于将扩展方法放在它们扩展的类型的命名空间中,在这种情况下:

 namespace System.Collections.Generic 

大多数情况下,使用该类型的人在顶部定义了using语句,因此IntelliSense也会在代码中找到它的扩展方法。

与许多编程问题一样,当你发现自己做了很多事情时,将它重构为一个方法:

 public static void MyAdd( this Dictionary dictionary, TKey key, TValue value) where TCollection : ICollection, new() { TCollection collection; if (!dictionary.TryGetValue(key, out collection)) { collection = new TCollection(); dictionary.Add(key, collection); } collection.Add(value); } 

好的,不同的方法:

 public static bool TryAddValue(this System.Collections.Generic.IDictionary> dictionary, TKey key, TValue value) { // Null check (useful or not, depending on your null checking approach) if (value == null) return false; List tempValue = default(List); try { if (!dictionary.TryGetValue(key, out tempValue)) { dictionary.Add(key, tempValue = new List()); } else { // Double null check (useful or not, depending on your null checking approach) if (tempValue == null) { dictionary[key] = (tempValue = new List()); } } tempValue.Add(value); return true; } catch { return false; } } 

通过这种方式,您必须“尝试将”值添加到通用List(显然可归于generics集合),null检查并尝试获取Dictionary中的现有键/值。 用法和示例:

 var x = new Dictionary>(); x.TryAddValue("test", null); // return false due to null value. Doesn't add the key x.TryAddValue("test", "ok"); // it works adding the key/value x.TryAddValue("test", "ok again"); // it works adding the value to the existing list 

希望能帮助到你。

那怎么样?

 var keyValues = dictionary[key] = dictionary.ContainsKey(key) ? dictionary[key] : new List(); keyValues.Add(aValueForKey);