2010-11-02 114 views
1

我想要一本字典,不会在词典中返回指定值的任意键,这样的:默认值.NET字典

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

+0

我处于同样的情况。我有各种业务对象类型的巨大集合。我想通过让Funcs字典应该返回标准Funcs或特殊情况下的Func来防止策略模式的极端使用,以防业务对象类型保证它。开放闭合原则。你最终在这里使用了什么? – Tormod 2011-03-20 17:43:57

+0

由于我的字典不是很大,我只填写缺失的条目。 – 2011-03-21 15:40:22

回答

7

重新实现词典从头开始(从IDictionary的<,>)是太多的努力

这确实是最好的选择。只需将Dictionary<,>封装为您班级的成员,并将所有成员都传递给Dictionary的代码。在这种情况下,您只需处理您希望有所不同的属性和方法。

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

+0

为什么当你可以委托时你会复制/粘贴? – 2013-01-19 21:58:11

2

我觉得Reed是正确的,Reimplementing Dictionary非常简单,如果这就是你需要的,那很好。

,但它似乎仍然有点小题大做,以创建一个新类来代替

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

 value = dict.GetOrDefault(key, "not specified") 
+4

好吧,问题是我有几个使用字典的消费者传递给他们。那些消费者不知道(并且一定不知道,否则你会得到SRP违规),缺少输入的默认值是多少。所以不是,它不只是取代它,它的替代:'someOtherServiceResponsibleForHandlingMissingKeys.GetValueFor(key)' – 2010-11-02 16:49:35

+0

然后你肯定需要去与里德的方法 – 2010-11-02 17:25:10

0

试试这个

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

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

+0

我想OP想要实现IDictionary 的东西。另外,我认为'if(!_dict.ContainsKey(key)){...}'可以通过'if(!dict.TryGetValue(key,out v)){...}'稍微更高效地实现。我不确定在查找失败时自动将条目添加到底层映射是否有意义。我查看了Scala的可变映射,并没有表现出这种行为。但我可以看到,无论如何。也许它应该是一个构造器设置。 – 2014-07-03 15:30:07

0

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

也许好老StringDictionary类会做你想做的。与Dictionary<string,string>不同,它的get_Item方法为字典中不存在的键返回null

0

这种扩展方法让我了解;

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.