基本上我想知道是否使用代码契约来确定ConcurrentDictionary中是否存在密钥是代码契约的可接受使用。它对我来说不合适,因为它不仅仅是参数检查,因为它取决于运行时字典的状态。
public class MyClass
{
private ConcurrentDictionary<string, object> someItems =
new ConcurrentDictionary<string, object>();
public object GetItem(string itemName)
{
Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(itemName));
// ?? Is this a correct alternative to checking for null???
Contract.Requires<KeyNotFoundException>(someItems.ContainsKey(itemName));
return someItems[itemName];
}
}
但是如果没问题的话,这是一个更简洁的方法,它有2个Contract.Requires和一个返回,通过下面的传统方式。
public class MyClass
{
private ConcurrentDictionary<string, object> someItems =
new ConcurrentDictionary<string, object>();
public object GetItem(string itemName)
{
Contract.Requires<ArgumentNullException>(!String.IsNullOrWhiteSpace(itemName));
// Traditional null check
var item = someItems[itemName];
if (item == null)
{
throw new KeyNotFoundException("Item " + itemName + " not found.");
}
return item;
}
}
答案 0 :(得分:0)
对我来说有点奇怪:类的内部状态(即someItems
字典的内容)绝对是不合同的一部分。你可以以这种方式使用它,但是合同检查应该让调用者知道到底出了什么问题。在这种情况下,调用者永远不会猜出哪些参数是允许的,哪些不是 - 即使在获得KeyNotFoundException
之后。
此外,在这种特殊情况下,如果在字典中找不到对象则抛出异常看起来不一致,在我看来返回null
会更有意义。
顺便说一句,在你的第一个例子中,itemName
在字典中被搜索了两次。