代码之家  ›  专栏  ›  技术社区  ›  THX-1138

默认值为.net字典

  •  2
  • THX-1138  · 技术社区  · 14 年前

    我想要一个字典,它将返回字典中没有的任何键的指定值,例如:

    var dict = new DictWithDefValues("not specified");
    dict.Add("bob78", "Smart");
    dict.Add("jane17", "Doe");
    Assert.AreEqual(dict["xxx"], "not specified");
    

    扩展System.Collections.Generics.Dictionary和重写TryGetValue不起作用,因为TryGetValue不是虚拟的。

    从头开始重新实现字典(来自IDictionary<,>)太费劲了。

    扩展方法不允许我用默认值“初始化”字典。我想让字典的使用者认为钥匙在那里,而不仅仅是 dict.GetOrDefault(key, "not specified");

    6 回复  |  直到 14 年前
        1
  •  7
  •   Reed Copsey    14 年前

    从头开始重新实现字典(来自IDictionary<,>)太费劲了

    这确实是最好的选择。只是封装一个 Dictionary<,> 作为类的成员,并将所有成员传递到字典的代码。在这种情况下,您只需要处理希望不同的属性和方法。

    我同意这是一个有点乏味的工作-但它可能不到5分钟的输入值,因为每个方法都可以传递到内部字典的实现。

        2
  •  5
  •   Conrad Frix    14 年前

    我认为里德是正确的,重新实现字典是非常简单的,如果这是你需要的,那就好了。

            dict.TryGetValue("xxx", out value);
            value = value ?? "not specified";
    

    具有

          value  = dict.GetOrDefault(key, "not specified")
    
        3
  •  1
  •   Steve Cooper    8 年前

    这个扩展方法让我通过了;

        public static TValue GetValueOrDefault<TKey, TValue>(this Dictionary<TKey, TValue> source, TKey key, TValue defaultValue = default(TValue))
        {
            TValue found;
            if (source.TryGetValue(key, out found))
            {
                return found;
            }
            else
            {
                return defaultValue;
            }
        }
    

    dict.GetValueOrDefault("foo", 0) // returns the key under "foo", or 0 if missing.
    
        4
  •  0
  •   John Raymund    13 年前

    我在.NET中创建了一个DefaultableDictionary,它完全符合您的要求!

    http://github.com/jsonmez/Defaultable-Dictionary

    博客文章 here

        5
  •  0
  •   Simon    12 年前

    试试这个

    public class DefaultDictionary<Tkey,Tvalue>
        where Tkey: IEquatable<Tkey>
    {
        private readonly Func<Tvalue> _getDefault;
        private Dictionary<Tkey, Tvalue> _dict;
    
        public DefaultDictionary(Func<Tvalue> getDefault = null)
        {
            if (getDefault == null)
            {
                _getDefault = () => default(Tvalue);
            }
            else
            {
                _getDefault = getDefault;
            }
            _dict = new Dictionary<Tkey, Tvalue>();
        }
    
        public Tvalue this[Tkey key]
        {
            get
            {
                if (!_dict.ContainsKey(key))
                {
                    _dict[key] = _getDefault();
                }
                return _dict[key];
            }
    
            set { _dict[key] = value; }
        }
    
        public bool ContainsKey(Tkey key)
        {
            return _dict.ContainsKey(key);
        }
    
        public override string ToString()
        {
            var sb = new StringBuilder();
            foreach (var kvp in _dict)
            {
                sb.AppendFormat("[{0}] : {1}", kvp.Key.ToString(), kvp.Value.ToString()).AppendLine();
            }
    
            return sb.ToString();
        }
    }
    

    您可以根据需要轻松地将包装器添加到其他方法和属性中。

        6
  •  0
  •   Tim Lovell-Smith    11 年前

    我注意到你的例子是一本字符串词典。在我自己的场景中,我也需要类似的行为。

    也许是老好人 StringDictionary 班级会做你想做的事。不像 Dictionary<string,string> 它的get-Item方法返回 null 对于字典中不存在的键。