Dictionary returning a default value if the key does not exist
本问题已经有最佳答案,请猛点这里访问。
我发现我现在经常在代码中使用当前的模式
1 2 3 4 5 |
或者有时
1 2 3 4 5 6 7 |
号
这两种方式都很迂回。我真正想要的是
1 | dictionary.GetValueOrDefault(key) |
现在,我可以为Dictionary类编写一个扩展方法,它可以为我实现这一点,但是我发现我可能缺少已经存在的东西。那么,有没有一种方法可以更容易地做到这一点,而不需要为字典编写扩展方法呢?
1 | dictionary.TryGetValue(key, out value); |
忽略返回值。但是,这实际上只是返回
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public static TValue GetValueOrDefault<TKey, TValue> (this IDictionary<TKey, TValue> dictionary, TKey key, TValue defaultValue) { TValue value; return dictionary.TryGetValue(key, out value) ? value : defaultValue; } public static TValue GetValueOrDefault<TKey, TValue> (this IDictionary<TKey, TValue> dictionary, TKey key, Func<TValue> defaultValueProvider) { TValue value; return dictionary.TryGetValue(key, out value) ? value : defaultValueProvider(); } |
号
(当然,您可能想让参数签入:)
我知道这是一篇老文章,我很喜欢扩展方法,但是这里有一个简单的类,当我需要默认值时,我经常使用它来处理字典。
我希望这只是基本字典类的一部分。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | public class DictionaryWithDefault<TKey, TValue> : Dictionary<TKey, TValue> { TValue _default; public TValue DefaultValue { get { return _default; } set { _default = value; } } public DictionaryWithDefault() : base() { } public DictionaryWithDefault(TValue defaultValue) : base() { _default = defaultValue; } public new TValue this[TKey key] { get { TValue t; return base.TryGetValue(key, out t) ? t : _default; } set { base[key] = value; } } } |
。
但是要小心。通过对
我创建了一个默认字典来完全满足您的要求!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 | using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; namespace DefaultableDictionary { public class DefaultableDictionary<TKey, TValue> : IDictionary<TKey, TValue> { private readonly IDictionary<TKey, TValue> dictionary; private readonly TValue defaultValue; public DefaultableDictionary(IDictionary<TKey, TValue> dictionary, TValue defaultValue) { this.dictionary = dictionary; this.defaultValue = defaultValue; } public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() { return dictionary.GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); } public void Add(KeyValuePair<TKey, TValue> item) { dictionary.Add(item); } public void Clear() { dictionary.Clear(); } public bool Contains(KeyValuePair<TKey, TValue> item) { return dictionary.Contains(item); } public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) { dictionary.CopyTo(array, arrayIndex); } public bool Remove(KeyValuePair<TKey, TValue> item) { return dictionary.Remove(item); } public int Count { get { return dictionary.Count; } } public bool IsReadOnly { get { return dictionary.IsReadOnly; } } public bool ContainsKey(TKey key) { return dictionary.ContainsKey(key); } public void Add(TKey key, TValue value) { dictionary.Add(key, value); } public bool Remove(TKey key) { return dictionary.Remove(key); } public bool TryGetValue(TKey key, out TValue value) { if (!dictionary.TryGetValue(key, out value)) { value = defaultValue; } return true; } public TValue this[TKey key] { get { try { return dictionary[key]; } catch (KeyNotFoundException) { return defaultValue; } } set { dictionary[key] = value; } } public ICollection<TKey> Keys { get { return dictionary.Keys; } } public ICollection<TValue> Values { get { var values = new List<TValue>(dictionary.Values) { defaultValue }; return values; } } } public static class DefaultableDictionaryExtensions { public static IDictionary<TKey, TValue> WithDefaultValue<TValue, TKey>(this IDictionary<TKey, TValue> dictionary, TValue defaultValue ) { return new DefaultableDictionary<TKey, TValue>(dictionary, defaultValue); } } } |
这个项目是一个IDictionary对象的简单修饰器,也是一个扩展方法,使其易于使用。
当试图访问不存在的键或枚举IDictionary中的所有值时,DefaultableDictionary将允许围绕提供默认值的字典创建包装。
示例:
关于使用情况的博客文章。
不,不存在这样的情况。扩展方法是一种可行的方法,您的名称(getValueOrDefault)是一个不错的选择。