如果键不存在,则字典返回默认值

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


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>();

}

这两种方式都感觉很round回。我真正想要的是


dictionary.GetValueOrDefault(key)

现在,我可以为字典类编写一个扩展方法,该方法可以为我完成此任务,但我发现可能会丢失一些已经存在的东西。因此,有没有一种方法可以更轻松地执行此操作,而无需编写字典的扩展方法?


蛊毒传说
浏览 1684回答 3
3回答

慕码人8056858

TryGetValue 已经为字典指定了类型的默认值,因此您可以使用:dictionary.TryGetValue(key, out value);并忽略返回值。然而,真正将刚刚返回default(TValue),而不是一些自定义的默认值(也没有,更有效,执行委托的结果)。框架中没有比它更强大的功能了。我建议两种扩展方法:public static TValue GetValueOrDefault<TKey, TValue>&nbsp; &nbsp; (this IDictionary<TKey, TValue> dictionary,&nbsp;&nbsp; &nbsp; &nbsp;TKey key,&nbsp; &nbsp; &nbsp;TValue defaultValue){&nbsp; &nbsp; TValue value;&nbsp; &nbsp; return dictionary.TryGetValue(key, out value) ? value : defaultValue;}public static TValue GetValueOrDefault<TKey, TValue>&nbsp; &nbsp; (this IDictionary<TKey, TValue> dictionary,&nbsp; &nbsp; &nbsp;TKey key,&nbsp; &nbsp; &nbsp;Func<TValue> defaultValueProvider){&nbsp; &nbsp; TValue value;&nbsp; &nbsp; return dictionary.TryGetValue(key, out value) ? value&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;: defaultValueProvider();}

米脂

我知道这是一篇老文章,我确实喜欢扩展方法,但是当我需要默认值时,这是我不时使用的简单类来处理字典。我希望这只是基本Dictionary类的一部分。public class DictionaryWithDefault<TKey, TValue> : Dictionary<TKey, TValue>{&nbsp; TValue _default;&nbsp; public TValue DefaultValue {&nbsp; &nbsp; get { return _default; }&nbsp; &nbsp; set { _default = value; }&nbsp; }&nbsp; public DictionaryWithDefault() : base() { }&nbsp; public DictionaryWithDefault(TValue defaultValue) : base() {&nbsp; &nbsp; _default = defaultValue;&nbsp; }&nbsp; public new TValue this[TKey key]&nbsp; {&nbsp; &nbsp; get {&nbsp;&nbsp; &nbsp; &nbsp; TValue t;&nbsp; &nbsp; &nbsp; return base.TryGetValue(key, out t) ? t : _default;&nbsp; &nbsp; }&nbsp; &nbsp; set { base[key] = value; }&nbsp; }}但是要当心。通过子类化和使用new(由于override本机Dictionary类型上不可用),如果将DictionaryWithDefault对象转换为普通对象Dictionary,则调用索引器将使用基本Dictionary实现(如果缺少则抛出异常),而不是子类的实现。

炎炎设计

我创建了一个DefaultableDictionary来完全满足您的要求!using System;using System.Collections;using System.Collections.Generic;using System.Collections.ObjectModel;namespace DefaultableDictionary {&nbsp; &nbsp; public class DefaultableDictionary<TKey, TValue> : IDictionary<TKey, TValue> {&nbsp; &nbsp; &nbsp; &nbsp; private readonly IDictionary<TKey, TValue> dictionary;&nbsp; &nbsp; &nbsp; &nbsp; private readonly TValue defaultValue;&nbsp; &nbsp; &nbsp; &nbsp; public DefaultableDictionary(IDictionary<TKey, TValue> dictionary, TValue defaultValue) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.dictionary = dictionary;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; this.defaultValue = defaultValue;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary.GetEnumerator();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; IEnumerator IEnumerable.GetEnumerator() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return GetEnumerator();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void Add(KeyValuePair<TKey, TValue> item) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dictionary.Add(item);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void Clear() {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dictionary.Clear();&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool Contains(KeyValuePair<TKey, TValue> item) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary.Contains(item);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dictionary.CopyTo(array, arrayIndex);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool Remove(KeyValuePair<TKey, TValue> item) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary.Remove(item);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public int Count {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return dictionary.Count; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool IsReadOnly {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return dictionary.IsReadOnly; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool ContainsKey(TKey key) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary.ContainsKey(key);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public void Add(TKey key, TValue value) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dictionary.Add(key, value);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool Remove(TKey key) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary.Remove(key);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public bool TryGetValue(TKey key, out TValue value) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!dictionary.TryGetValue(key, out value)) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; value = defaultValue;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return true;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public TValue this[TKey key] {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; try&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return dictionary[key];&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } catch (KeyNotFoundException) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return defaultValue;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; set { dictionary[key] = value; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public ICollection<TKey> Keys {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return dictionary.Keys; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; public ICollection<TValue> Values {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var values = new List<TValue>(dictionary.Values) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; defaultValue&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return values;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public static class DefaultableDictionaryExtensions {&nbsp; &nbsp; &nbsp; &nbsp; public static IDictionary<TKey, TValue> WithDefaultValue<TValue, TKey>(this IDictionary<TKey, TValue> dictionary, TValue defaultValue ) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return new DefaultableDictionary<TKey, TValue>(dictionary, defaultValue);&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}该项目是IDictionary对象的简单装饰器,是一种易于使用的扩展方法。DefaultableDictionary将允许在尝试访问不存在的键或枚举IDictionary中的所有值的字典周围创建提供默认值的字典包装。例: var dictionary = new Dictionary<string, int>().WithDefaultValue(5);
打开App,查看更多内容
随时随地看视频慕课网APP