具有默认值的.net字典
我想要一个字典,它将为字典中不存在的任何键返回指定值,类似于:具有默认值的.net字典,.net,dictionary,.net,Dictionary,我想要一个字典,它将为字典中不存在的任何键返回指定值,类似于: 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无效,因为TryGe
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)重新实现字典太费劲了
扩展方法不允许我用默认值“初始化”字典。我希望字典的使用者认为键在那里,而不仅仅是dodict.GetOrDefault(键,“未指定”)代码>
从头开始(从IDictionary)重新实现字典太费劲了
这确实是最好的选择。只需将字典
封装为类的成员,并将所有成员传递给字典的代码。在这种情况下,您只需要处理希望不同的属性和方法
我同意这是一项有点枯燥的工作——但可能不到5分钟的打字时间,因为每个方法都可以传递给内部字典的实现。我认为Reed的观点是正确的,重新实现字典非常简单,如果这是您需要的,那就好了
但是,创建一个新类来替换它似乎还是有些过分
dict.TryGetValue("xxx", out value);
value = value ?? "not specified";
与
我在.NET中创建了一个DefaultableDictionary,它完全符合您的要求
博客帖子。试试这个
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();
}
}
公共类DefaultDictionary
其中Tkey:IEquatable
{
私有只读函数_getDefault;
私人词典;
公共默认字典(Func getDefault=null)
{
if(getDefault==null)
{
_getDefault=()=>default(Tvalue);
}
其他的
{
_getDefault=getDefault;
}
_dict=新字典();
}
公共Tvalue此[Tkey]
{
得到
{
如果(!_dict.ContainsKey(键))
{
_dict[key]=\u getDefault();
}
返回_dict[键];
}
设置{u dict[key]=value;}
}
公共bool ContainsKey(Tkey)
{
返回目录ContainsKey(键);
}
公共重写字符串ToString()
{
var sb=新的StringBuilder();
foreach(var kvp输入)
{
AppendFormat(“[{0}]:{1}”,kvp.Key.ToString(),kvp.Value.ToString()).AppendLine();
}
使某人返回字符串();
}
}
您可以根据需要轻松地向其他方法和属性添加包装器。我注意到您的示例是字符串字典。在我自己的场景中,我也需要类似的行为
也许好的StringDictionary
类可以满足您的需要。与Dictionary
不同,它的get\u Item方法为Dictionary中不存在的键返回null
。这个扩展方法让我通过
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;
}
}
问题是,我很少有消费者使用传递给他们的词典。这些使用者不知道(而且一定不知道,否则您会违反SRP)缺少条目的默认值是什么。因此,不,这不仅仅是替换它,而是替换:someotherservicesresponsibleforhandlingmissingkeys.GetValueFor(key)
,那么在同样的情况下,您肯定需要使用Reed的方法。我收集了大量不同的业务对象类型。我希望通过使用Func字典来充分利用策略模式,这些字典应该返回标准Func或特殊情况Func,以防业务对象类型需要它。开闭原理。你们最后在这里用了什么?因为我的字典不大,所以我只填写遗漏的条目。我不会依赖你们索引器getter中的异常。改用if(x.ContainsKey(…)
。既然可以委托,为什么还要复制/粘贴?我想OP想要实现IDictionary的东西。另外,我认为if(!\u dict.ContainsKey(key)){…}
可以通过if(!dict.TryGetValue(key,out v)){…}
更有效地实现。我不确定在查找失败时自动向基础映射添加条目是否有意义。我检查了Scala的可变映射,它没有表现出这种行为。但我可以预见到这两种情况。也许它应该是一个构造函数设置。
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.