为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
蛊毒传说 2019-12-21 11:27:11
我发现自己如今在我的代码中经常使用当前模式var dictionary = new Dictionary<type, IList<othertype>>();// Add stuff to dictionaryvar 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 dictionaryIList<othertype> somethingElse;if(!dictionary.TryGetValue(key, out somethingElse) {    somethingElse = new List<othertype>();}这两种方式都感觉很round回。我真正想要的是dictionary.GetValueOrDefault(key)现在,我可以为字典类编写一个扩展方法,该方法可以为我完成此任务,但我发现可能会丢失一些已经存在的东西。因此,有没有一种方法可以更轻松地执行此操作,而无需编写字典的扩展方法?
查看完整描述

3 回答

?
慕码人8056858

TA贡献1803条经验 获得超6个赞

TryGetValue 已经为字典指定了类型的默认值,因此您可以使用:


dictionary.TryGetValue(key, out value);

并忽略返回值。然而,真正将刚刚返回default(TValue),而不是一些自定义的默认值(也没有,更有效,执行委托的结果)。框架中没有比它更强大的功能了。我建议两种扩展方法:


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

}


查看完整回答
反对 回复 2019-12-21
?
米脂

TA贡献1836条经验 获得超3个赞

我知道这是一篇老文章,我确实喜欢扩展方法,但是当我需要默认值时,这是我不时使用的简单类来处理字典。


我希望这只是基本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; }

  }

}

但是要当心。通过子类化和使用new(由于override本机Dictionary类型上不可用),如果将DictionaryWithDefault对象转换为普通对象Dictionary,则调用索引器将使用基本Dictionary实现(如果缺少则抛出异常),而不是子类的实现。


查看完整回答
反对 回复 2019-12-21
?
炎炎设计

TA贡献1808条经验 获得超4个赞

我创建了一个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将允许在尝试访问不存在的键或枚举IDictionary中的所有值的字典周围创建提供默认值的字典包装。


例: var dictionary = new Dictionary<string, int>().WithDefaultValue(5);


查看完整回答
反对 回复 2019-12-21
  • 3 回答
  • 0 关注
  • 1666 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信