在生产中,这段代码(C#,.NET 4.5.1)正在抛出一个ArgumentException
来表明这一点
An item with the same key has already been added.
代码:
public MyClass()
{
this.MyContent = new Dictionary<string, string>();
}
public IDictionary<string, string> MyContent { get; private set; }
public void AddOrUpdateDictionary(string key, string value)
{
if (this.MyContent.ContainsKey(key))
{
this.MyContent[key] = string.Concat(this.MyContent[key], value);
}
else
{
this.MyContent.Add(key, value);
}
}
但是,我无法在单元测试中重新创建错误。例如。这表现得如预期的那样 -
[TestMethod]
public void AddOrUpdateDictionary_WhenAddingSecondValue_ValueIsAppended()
{
const string InputValue1 = "Value1";
const string InputValue2 = "Value2";
string expectedValue = string.Concat(InputValue1, InputValue2);
var obj = new MyClass();
obj.AddOrUpdateDictionary("Key", InputValue1);
obj.AddOrUpdateDictionary("Key", InputValue2);
Assert.AreEqual(expectedValue, obj.MyContent["Key"]);
}
造成这种情况的原因是什么?我认为ContainsKey
会使代码安全。
我错过了一些奇怪的线程吗?此代码位于MVC站点中的模型上,没有任何实例是静态的。
答案 0 :(得分:2)
Assuming the problem is thread related and it is allowed to change the type of dictionary, you could use a ConcurrentDictionary. It exposes a method (AddOrUpdate) that can do exactly what's intended: either add the value or refactor the value based on the present value:
class MyClass
{
public MyClass()
{
this.content = new ConcurrentDictionary<string, string>();
}
ConcurrentDictionary<string, string> content;
public IDictionary<string, string> MyContent { get { return content; } }
public void AddOrUpdateDictionary(string key, string value)
{
content.AddOrUpdate(key, value, (k, contentValue) => string.Concat(contentValue, value));
}
}
答案 1 :(得分:0)
You may want to use ConcurrentDictionary<T1, T2>
So it would be like:
public void AddOrUpdateDictionary(string key, string value)
{
if (this.MyContent.ContainsKey(key))
{
this.MyContent[key] = string.Concat(this.MyContent[key], value);
}
else
{
this.MyContent.AddOrUpdate(key, value, (x, y) => value);
}
}