我有一个将字符串映射到双精度的字典。
我有这一行:
leaves[child.Value] += branchProbability;
崩溃是因为而不是: 如果找不到,则添加默认值0,返回0,将其添加到branchProbability,设置新值= 0 + branchProbability,它通过对引发KeyNotFoundException的键执行get来启动。
我唯一能想到的是:
if(!leaves.ContainsKey(child.Value))
leaves[child.Value] = branchProbability;
else
leaves[child.Value] += branchProbability;
但这需要额外查找contains。
在避免包含检查的同时,是否有更有效的方法来执行此操作?
答案 0 :(得分:2)
以下代码定义(并测试,如果将其粘贴到LinqPad中),这个类将允许您使用+=
执行此操作。但是,如果您将字典传递到很多地方,它将无法工作,因为它必须使用new
隐藏索引器而不是覆盖它(Dictionary
的索引器不是虚拟的)。
解决这个问题的一种方法是创建DefaultingDictionary
作为IDictionary<TKey, TValue>
的实现者,并在具有私有成员Dictionary
的类中,并将所有调用委托给IDictionary
上的方法 - 除了索引器,你自己做的。您仍然无法将此传递给期望Dictionary
的内容,但您可以更改这些内容以接受IDictionary
。
void Main()
{
var dict = new DefaultingDictionary<string, double>();
dict["one"] = 1;
dict["one"] += 1;
dict["two"] += 1;
Console.WriteLine(dict["one"]);
Console.WriteLine(dict["two"]);
}
class DefaultingDictionary<TKey, TValue> : Dictionary<TKey, TValue>
{
public new TValue this[TKey key]
{
get
{
TValue v;
if(TryGetValue(key, out v))
{
return v;
}
return default(TValue);
}
set
{
base[key] = value;
}
}
}
老实说,这只是能够做+=
事情的很多工作。真的,你应该做检查。这没有性能优势,只会让你的代码变得更复杂。如果您进行检查,那么阅读它的人就会明白究竟发生了什么。
答案 1 :(得分:-3)
我不确定你能做多少,也许介绍一个三元运算符而不是if..else会在论文上看起来不错。但就可读性而言,我会建议你采用的方式。
leaves[child.value] = leaves.ContainsKey(child.value)
? leaves[child.value] + branchProbability
: branchProbability;