字典返回一个默认值,如果该键不存在

现在我发现自己在我的代码中经常使用当前的模式

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在本地Dictionarytypes上不可用),如果DictionaryWithDefault对象被上传到普通的Dictionary ,调用索引器将使用基本的Dictionary实现(如果丢失则抛出exception)而不是子类的实现。

不,没有这样的东西存在。 扩展方法是要走的路,你的名字( GetValueOrDefault )是一个不错的select。