字典抛出参数异常,即使受ContainsKey保护
本文关键字:ContainsKey 保护 参数 异常 字典 | 更新日期: 2023-09-27 17:59:46
在生产中,此代码(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站点中的一个模型上,没有任何实例是静态的。
假设问题与线程有关,并且允许更改字典的类型,则可以使用ConcurrentDictionary。它公开了一个方法(AddOrUpdate),该方法可以完全按照预期执行:添加值或根据当前值重构值:
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));
}
}
You may want to use ConcurrentDictionary<T1, T2>
所以它会像:
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);
}
}