字典返回一个默认值,如果该键不存在
现在我发现自己在我的代码中经常使用当前的模式
var dictionary = new Dictionary<type, IList<othertype>>(); // Add stuff to dictionary var somethingElse = dictionary.ContainsKey(key) ? dictionary[key] : new List<othertype>(); // Do work with the somethingelse variable
或者有时候
var dictionary = new Dictionary<type, IList<othertype>>(); // Add stuff to dictionary IList<othertype> somethingElse; if(!dictionary.TryGetValue(key, out somethingElse) { somethingElse = new List<othertype>(); }
这两种方式都觉得很迂回。 我真正想要的是类似的东西
dictionary.GetValueOrDefault(key)
现在,我可以为字典类写一个扩展方法,但是我想我可能会丢失已经存在的东西。 那么,有没有办法以一种更容易的方式来做到这一点,而不需要在字典中使用扩展方法呢?
TryGetValue
已经将types的默认值分配给字典,所以你可以使用:
dictionary.TryGetValue(key, out value);
并忽略返回值。 然而,这真的只会返回default(TValue)
,而不是一些自定义的默认值(更有用的是,执行委托的结果)。 没有什么更强大的框架内置。 我会build议两种扩展方法:
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(); }
(当然,你可能想把参数检查)
我创build了一个DefaultableDictionary来完成你所要求的!
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对象的修饰器和一个扩展方法,使其易于使用。
DefaultableDictionary将允许创build一个字典的包装,当试图访问一个不存在的键或通过一个IDictionary中的所有值枚举时提供一个默认值。
例子: var dictionary = new Dictionary<string, int>().WithDefaultValue(5);
博客上的使用情况也是如此。
我知道这是一个旧的post,我喜欢扩展方法,但这里有一个简单的类,我不时地使用字典,当我需要默认值。
我希望这只是基础Dictionary类的一部分。
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; } } }
小心,但是。 通过inheritance和使用new
(因为override
在本地Dictionary
types上不可用),如果DictionaryWithDefault
对象被上传到普通的Dictionary
,调用索引器将使用基本的Dictionary
实现(如果丢失则抛出exception)而不是子类的实现。
不,没有这样的东西存在。 扩展方法是要走的路,你的名字( GetValueOrDefault )是一个不错的select。